OOFEM 3.0
Loading...
Searching...
No Matches
structuralmaterial.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
36#include "domain.h"
37#include "verbose.h"
41#include "gausspoint.h"
42#include "floatmatrix.h"
43#include "floatarray.h"
44#include "floatmatrixf.h"
45#include "floatarrayf.h"
46#include "mathfem.h"
47#include "engngm.h"
48#include "fieldmanager.h"
49#include "dynamicinputrecord.h"
50
51namespace oofem {
52std::array< std::array< int, 3 >, 3 >StructuralMaterial::vIindex = {{
53 {1, 6, 5},
54 {9, 2, 4},
55 {8, 7, 3}
56}};
57
58std::array< std::array< int, 3 >, 3 >StructuralMaterial::svIndex = {{
59 {1, 6, 5},
60 {6, 2, 4},
61 {5, 4, 3}
62}};
63
64
65
67
68
69bool
71//
72// returns whether receiver supports given mode
73//
74{
75 return mode == _3dMat || mode == _PlaneStress || mode == _PlaneStrain || mode == _1dMat ||
76 mode == _PlateLayer || mode == _2dBeamLayer || mode == _Fiber;
77}
78
79void
80StructuralMaterial::giveCharacteristicMatrix(FloatMatrix &answer, MatResponseMode type, GaussPoint* gp, TimeStep *tStep) const
81{
82 if (type == TangentStiffness) {
83 this->giveStiffnessMatrix(answer, MatResponseMode::TangentStiffness, gp, tStep);
84 } else {
85 OOFEM_ERROR("Not implemented");
86 }
87}
88
89void
90StructuralMaterial::giveCharacteristicVector(FloatArray &answer, FloatArray& flux, MatResponseMode type, GaussPoint* gp, TimeStep *tStep) const {
91 if (type == Stress) {
92 return this->giveRealStressVector(answer, gp, flux, tStep);
93 } else {
94 OOFEM_ERROR("Not implemented");
95 }
96}
97
98void
99StructuralMaterial::giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep) const
100{
102 MaterialMode mode = gp->giveMaterialMode();
103 if ( mode == _3dMat ) {
104 answer = this->giveRealStressVector_3d(reducedStrain, gp, tStep);
105 } else if ( mode == _3dDegeneratedShell ) {
106 answer = this->giveRealStressVector_3d(reducedStrain, gp, tStep);
107 } else if ( mode == _PlaneStrain ) {
108 answer = this->giveRealStressVector_PlaneStrain(reducedStrain, gp, tStep);
109 } else if ( mode == _PlaneStress ) {
110 answer = this->giveRealStressVector_PlaneStress(reducedStrain, gp, tStep);
111 } else if ( mode == _1dMat ) {
112 answer = this->giveRealStressVector_1d(reducedStrain, gp, tStep);
113 } else if ( mode == _2dBeamLayer ) {
114 answer = this->giveRealStressVector_2dBeamLayer(reducedStrain, gp, tStep);
115 } else if ( mode == _PlateLayer ) {
116 answer = this->giveRealStressVector_PlateLayer(reducedStrain, gp, tStep);
117 } else if ( mode == _Fiber ) {
118 answer = this->giveRealStressVector_Fiber(reducedStrain, gp, tStep);
119 } else if ( mode == _2dPlateSubSoil ) {
120 answer = this->giveRealStressVector_2dPlateSubSoil(reducedStrain, gp, tStep);
121 } else if ( mode == _3dBeamSubSoil ) {
122 answer = this->giveRealStressVector_3dBeamSubSoil(reducedStrain, gp, tStep);
123 }
124}
125
126
129{
130 OOFEM_ERROR("3d mode not supported");
131}
132
133
136{
137 OOFEM_ERROR("Warping mode not supported");
138}
139
140
143{
144 auto vS = this->giveRealStressVector_3d(assemble< 6 >(strain, { 0, 1, 2, 5 }), gp, tStep);
145 return vS [ { 0, 1, 2, 5 } ];
146}
147
148
150StructuralMaterial::giveRealStressVector_StressControl(const FloatArray &reducedStrain, const IntArray &strainControl, GaussPoint *gp, TimeStep *tStep) const
151{
152 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
153
154 IntArray stressControl;
155 FloatArray vE, increment_vE, vS, reducedvS;
156 FloatMatrix tangent, reducedTangent;
157 // Iterate to find full vE.
158 // Compute the negated the array of control since we need stressControl as well;
159
160 stressControl.resize(6 - strainControl.giveSize() );
161 for ( int i = 1, j = 1; i <= 6; i++ ) {
162 if ( !strainControl.contains(i) ) {
163 stressControl.at(j++) = i;
164 }
165 }
166
167 // Initial guess;
168 vE = status->giveStrainVector();
169 for ( int i = 1; i <= strainControl.giveSize(); ++i ) {
170 vE.at(strainControl.at(i) ) = reducedStrain.at(i);
171 }
172
173 // Iterate to find full vE.
174 FloatArray answer;
175 int SCManrSteps = 10;
176 FloatMatrix reducedTangentInverse;
177 for ( int k = 0; k < SCMaxiter; k++ ) { // Allow for a generous 100000 iterations.
178 vS = this->giveRealStressVector_3d(vE, gp, tStep);
179 // For debugging the iterations:
180 //vE.printYourself("vE");
181 //vS.printYourself("vS");
182 reducedvS.beSubArrayOf(vS, stressControl);
183 //printf("%3d: %e\n", k, reducedvS.computeNorm());
184 // Pick out the (response) stresses for the controlled strains
185 answer.beSubArrayOf(vS, strainControl);
186 if ( ( reducedvS.computeNorm() <= this->SCRelTol * vS.computeNorm() && k >= 1 ) || ( reducedvS.computeNorm() < this->SCAbsTol ) ) { // Absolute tolerance right now (with at least one iteration)
190 //if ( reducedvS.computeNorm() <= 1e-6 * answer.computeNorm() ) {
191 return answer;
192 }
193
194 if ( ( k == 0 ) || ( ( ( this->SCStiffMode == TangentStiffness ) || ( this->SCStiffMode == SecantStiffness ) ) && ( k % SCManrSteps == 0 ) ) ) {
195 tangent = this->give3dMaterialStiffnessMatrix(this->SCStiffMode, gp, tStep);
196 reducedTangent.beSubMatrixOf(tangent, stressControl, stressControl);
197 if ( reducedTangentInverse.beInverseOf(reducedTangent) == false ) {
198 // in case of singularity revert to safe elastic stiffness
199 tangent = this->give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
200 reducedTangent.beSubMatrixOf(tangent, stressControl, stressControl);
201 reducedTangentInverse.beInverseOf(reducedTangent);
202 }
203 }
204 //reducedTangent.printYourself();
205 //reducedTangent.solveForRhs(reducedvS, increment_vE);
206 increment_vE.beProductOf(reducedTangentInverse, reducedvS);
207 increment_vE.negated();
208 vE.assemble(increment_vE, stressControl);
209 //vE.printYourself("vE");
210 }
211
212 OOFEM_ERROR("Iteration did not converge after 100000 iterations\nS.norm=%e, err=%e, relErr=%e", vS.computeNorm(), reducedvS.computeNorm(), reducedvS.computeNorm() / vS.computeNorm() );
213}
214
215
218// calculates stress vector (6 components) with assumption of sigma_z = 0
219// used by MITC4Shell
220{
221 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
222
223 IntArray stressControl;
224 FloatArray vE, increment_vE, vS, reducedvS;
225 FloatMatrix tangent, reducedTangent;
226 // Iterate to find full vE.
227 // Compute the negated the array of control since we need stressControl as well;
228
229 stressControl.resize(6 - strainControl.giveSize() );
230 for ( int i = 1, j = 1; i <= 6; i++ ) {
231 if ( !strainControl.contains(i) ) {
232 stressControl.at(j++) = i;
233 }
234 }
235
236 // Initial guess;
237 vE = status->giveStrainVector();
238 vE = strain;
239 // step 0: vE = {., ., 0, ., ., .}
240 // step n: vE = {., ., sum(ve(n)), ., ., .}
241
242 // Iterate to find full vE.
243 //vE.printYourself("vE");
244 FloatArray answer;
245 for ( int k = 0; k < SCMaxiter; k++ ) { // Allow for a generous 100 iterations.
246 answer = this->giveRealStressVector_3d(vE, gp, tStep);
247 // step 0: answer = full stress vector
248 // step n: answer = {., ., ->0, ., ., .}
249 reducedvS.beSubArrayOf(answer, stressControl);
250 if ( ( reducedvS.computeNorm() <= this->SCRelTol * answer.computeNorm() && k >= 1 ) || ( reducedvS.computeNorm() < this->SCAbsTol ) ) { // Absolute tolerance right now (with at least one iteration)
251 return answer;
252 }
253 //reducedvS.printYourself("Vs");
254 tangent = this->give3dMaterialStiffnessMatrix(this->SCStiffMode, gp, tStep);
255 reducedTangent.beSubMatrixOf(tangent, stressControl, stressControl);
256 //reducedTangent.printYourself("d");
257 reducedTangent.solveForRhs(reducedvS, increment_vE);
258 increment_vE.negated();
259 //increment_vE.printYourself("iVe");
260 vE.assemble(increment_vE, stressControl);
261 //vE.printYourself("vE");
262 }
263
264 OOFEM_WARNING("Iteration did not converge");
265 return FloatArray();
266}
267
268
269
270
273{
274 IntArray strainControl;
275 StructuralMaterial::giveVoigtSymVectorMask(strainControl, _PlaneStress);
276 return this->giveRealStressVector_StressControl(reducedStrain, strainControl, gp, tStep);
277}
278
279
282{
283 IntArray strainControl;
284 StructuralMaterial::giveVoigtSymVectorMask(strainControl, _1dMat);
285 return this->giveRealStressVector_StressControl(reducedStrain, strainControl, gp, tStep);
286}
287
288
291{
292 IntArray strainControl;
293 StructuralMaterial::giveVoigtSymVectorMask(strainControl, _2dBeamLayer);
294 return this->giveRealStressVector_StressControl(reducedStrain, strainControl, gp, tStep);
295}
296
297
300{
301 IntArray strainControl;
302 StructuralMaterial::giveVoigtSymVectorMask(strainControl, _PlateLayer);
303 return this->giveRealStressVector_StressControl(reducedStrain, strainControl, gp, tStep);
304}
305
306
309{
310 IntArray strainControl;
311 StructuralMaterial::giveVoigtSymVectorMask(strainControl, _Fiber);
312 return this->giveRealStressVector_StressControl(reducedStrain, strainControl, gp, tStep);
313}
314
315
318{
319 OOFEM_ERROR("2dPlateSubSoil mode not supported");
320}
321
324{
325 OOFEM_ERROR("3dBeamSubSoil mode not supported");
326}
327
328
331{
332 // Default implementation used if this method is not overloaded by the particular material model.
333 // 1) Compute Green-Lagrange strain and call standard method for small strains.
334 // 2) Treat stress as second Piola-Kirchhoff stress and convert to first Piola-Kirchhoff stress.
335 // 3) Set state variables F, P
336
337 auto F = from_voigt_form_9(vF);
338 auto E = 0.5 * ( Tdot(F, F) - eye< 3 >() );
339 auto vE = to_voigt_strain_33(E);
340 auto vS = this->giveRealStressVector_3d(vE, gp, tStep);
341
342 // Compute first PK stress from second PK stress
343 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
344 auto S = from_voigt_stress_6(vS);
345 auto P = dot(F, S);
346 auto vP = to_voigt_form_33(P);
347 status->letTempPVectorBe(vP);
348 status->letTempFVectorBe(vF);
349
350 return vP;
351}
352
353
356{
357 auto vP = this->giveFirstPKStressVector_3d(assemble< 9 >(vF, { 0, 1, 2, 5, 8 }), gp, tStep);
358 return vP [ { 0, 1, 2, 5, 8 } ];
359}
360
361
362
363
364
367{
368 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
369
370 IntArray P_control;
371 FloatArray vF, increment_vF, vP, reducedvP;
372 FloatMatrix tangent, reducedTangent;
373 // Iterate to find full vF.
374 // Compute the negated the array of control since we need stressControl as well;
375 P_control.resize( 9 - F_control.giveSize() );
376 for ( int i = 1, j = 1; i <= 9; i++ ) {
377 if ( !F_control.contains(i) ) {
378 P_control.at(j++) = i;
379 }
380 }
381
382 // Initial guess;
383 vF = status->giveFVector();
384 for ( int i = 1; i <= F_control.giveSize(); ++i ) {
385 vF.at( F_control.at(i) ) = reducedvF.at(i);
386 }
387
388 // Iterate to find full vF.
389 FloatArray answer;
390 for ( int k = 0; k < SCMaxiter; k++ ) { // Allow for a generous 100 iterations.
391 vP = this->giveFirstPKStressVector_3d(vF, gp, tStep);
392 reducedvP.beSubArrayOf(vP, P_control);
393 // Pick out the (response) stresses for the controlled strains
394 answer.beSubArrayOf(vP, F_control);
395 if ( reducedvP.computeNorm() <= 1e-6 * answer.computeNorm() && k >= 1 ) {
396 return answer;
397 }
398
399 tangent = this->give3dMaterialStiffnessMatrix_dPdF(TangentStiffness, gp, tStep);
400 reducedTangent.beSubMatrixOf(tangent, P_control, P_control);
401 reducedTangent.solveForRhs(reducedvP, increment_vF);
402 increment_vF.negated();
403 vF.assemble(increment_vF, P_control);
404 }
405
406 OOFEM_ERROR("Iteration did not converge");
407}
408
409
410
411
414{
415 IntArray FControl;
416 StructuralMaterial::giveVoigtVectorMask(FControl, _PlaneStress);
417 return this->giveRealStressVector_StressControl(reducedvF, FControl, gp, tStep);
418}
419
420
423{
424 IntArray FControl;
425 StructuralMaterial::giveVoigtVectorMask(FControl, _PlaneStress);
426 return this->giveRealStressVector_StressControl(reducedvF, FControl, gp, tStep);
427}
428
429
432{
433 // Converts the reduced dSdE-stiffness to reduced dPdF-sitiffness for different MaterialModes
434 // Performs the following operation dPdF = I_ik * S_jl + F_im F_kn C_mjnl,
435 // See for example: G.A. Holzapfel, Nonlinear Solid Mechanics: A Continuum Approach for
436 // Engineering, 2000, ISBN-10: 0471823198.
437
438 //Save terms associated with H = [du/dx, dv/dy, dw/dz, dv/dz, du/dz, du/dy, dw/dy, dw/dx, dv/dx]
440
441#if 1
442 answer(0, 0) = F [ 0 ] * C(0, 0) * F [ 0 ] + F [ 0 ] * C(0, 5) * F [ 5 ] + F [ 0 ] * C(0, 4) * F [ 4 ] + F [ 5 ] * C(5, 0) * F [ 0 ] + F [ 5 ] * C(5, 5) * F [ 5 ] + F [ 5 ] * C(5, 4) * F [ 4 ] + F [ 4 ] * C(4, 0) * F [ 0 ] + F [ 4 ] * C(4, 5) * F [ 5 ] + F [ 4 ] * C(4, 4) * F [ 4 ] + S [ 0 ];
443 answer(0, 1) = F [ 0 ] * C(0, 5) * F [ 8 ] + F [ 0 ] * C(0, 1) * F [ 1 ] + F [ 0 ] * C(0, 3) * F [ 3 ] + F [ 5 ] * C(5, 5) * F [ 8 ] + F [ 5 ] * C(5, 1) * F [ 1 ] + F [ 5 ] * C(5, 3) * F [ 3 ] + F [ 4 ] * C(4, 5) * F [ 8 ] + F [ 4 ] * C(4, 1) * F [ 1 ] + F [ 4 ] * C(4, 3) * F [ 3 ] + 0.0;
444 answer(0, 2) = F [ 0 ] * C(0, 4) * F [ 7 ] + F [ 0 ] * C(0, 3) * F [ 6 ] + F [ 0 ] * C(0, 2) * F [ 2 ] + F [ 5 ] * C(5, 4) * F [ 7 ] + F [ 5 ] * C(5, 3) * F [ 6 ] + F [ 5 ] * C(5, 2) * F [ 2 ] + F [ 4 ] * C(4, 4) * F [ 7 ] + F [ 4 ] * C(4, 3) * F [ 6 ] + F [ 4 ] * C(4, 2) * F [ 2 ] + 0.0;
445 answer(0, 3) = F [ 0 ] * C(0, 4) * F [ 8 ] + F [ 0 ] * C(0, 3) * F [ 1 ] + F [ 0 ] * C(0, 2) * F [ 3 ] + F [ 5 ] * C(5, 4) * F [ 8 ] + F [ 5 ] * C(5, 3) * F [ 1 ] + F [ 5 ] * C(5, 2) * F [ 3 ] + F [ 4 ] * C(4, 4) * F [ 8 ] + F [ 4 ] * C(4, 3) * F [ 1 ] + F [ 4 ] * C(4, 2) * F [ 3 ] + 0.0;
446 answer(0, 4) = F [ 0 ] * C(0, 4) * F [ 0 ] + F [ 0 ] * C(0, 3) * F [ 5 ] + F [ 0 ] * C(0, 2) * F [ 4 ] + F [ 5 ] * C(5, 4) * F [ 0 ] + F [ 5 ] * C(5, 3) * F [ 5 ] + F [ 5 ] * C(5, 2) * F [ 4 ] + F [ 4 ] * C(4, 4) * F [ 0 ] + F [ 4 ] * C(4, 3) * F [ 5 ] + F [ 4 ] * C(4, 2) * F [ 4 ] + S [ 4 ];
447 answer(0, 5) = F [ 0 ] * C(0, 5) * F [ 0 ] + F [ 0 ] * C(0, 1) * F [ 5 ] + F [ 0 ] * C(0, 3) * F [ 4 ] + F [ 5 ] * C(5, 5) * F [ 0 ] + F [ 5 ] * C(5, 1) * F [ 5 ] + F [ 5 ] * C(5, 3) * F [ 4 ] + F [ 4 ] * C(4, 5) * F [ 0 ] + F [ 4 ] * C(4, 1) * F [ 5 ] + F [ 4 ] * C(4, 3) * F [ 4 ] + S [ 5 ];
448 answer(0, 6) = F [ 0 ] * C(0, 5) * F [ 7 ] + F [ 0 ] * C(0, 1) * F [ 6 ] + F [ 0 ] * C(0, 3) * F [ 2 ] + F [ 5 ] * C(5, 5) * F [ 7 ] + F [ 5 ] * C(5, 1) * F [ 6 ] + F [ 5 ] * C(5, 3) * F [ 2 ] + F [ 4 ] * C(4, 5) * F [ 7 ] + F [ 4 ] * C(4, 1) * F [ 6 ] + F [ 4 ] * C(4, 3) * F [ 2 ] + 0.0;
449 answer(0, 7) = F [ 0 ] * C(0, 0) * F [ 7 ] + F [ 0 ] * C(0, 5) * F [ 6 ] + F [ 0 ] * C(0, 4) * F [ 2 ] + F [ 5 ] * C(5, 0) * F [ 7 ] + F [ 5 ] * C(5, 5) * F [ 6 ] + F [ 5 ] * C(5, 4) * F [ 2 ] + F [ 4 ] * C(4, 0) * F [ 7 ] + F [ 4 ] * C(4, 5) * F [ 6 ] + F [ 4 ] * C(4, 4) * F [ 2 ] + 0.0;
450 answer(0, 8) = F [ 0 ] * C(0, 0) * F [ 8 ] + F [ 0 ] * C(0, 5) * F [ 1 ] + F [ 0 ] * C(0, 4) * F [ 3 ] + F [ 5 ] * C(5, 0) * F [ 8 ] + F [ 5 ] * C(5, 5) * F [ 1 ] + F [ 5 ] * C(5, 4) * F [ 3 ] + F [ 4 ] * C(4, 0) * F [ 8 ] + F [ 4 ] * C(4, 5) * F [ 1 ] + F [ 4 ] * C(4, 4) * F [ 3 ] + 0.0;
451 answer(1, 0) = F [ 8 ] * C(5, 0) * F [ 0 ] + F [ 8 ] * C(5, 5) * F [ 5 ] + F [ 8 ] * C(5, 4) * F [ 4 ] + F [ 1 ] * C(1, 0) * F [ 0 ] + F [ 1 ] * C(1, 5) * F [ 5 ] + F [ 1 ] * C(1, 4) * F [ 4 ] + F [ 3 ] * C(3, 0) * F [ 0 ] + F [ 3 ] * C(3, 5) * F [ 5 ] + F [ 3 ] * C(3, 4) * F [ 4 ] + 0.0;
452 answer(1, 1) = F [ 8 ] * C(5, 5) * F [ 8 ] + F [ 8 ] * C(5, 1) * F [ 1 ] + F [ 8 ] * C(5, 3) * F [ 3 ] + F [ 1 ] * C(1, 5) * F [ 8 ] + F [ 1 ] * C(1, 1) * F [ 1 ] + F [ 1 ] * C(1, 3) * F [ 3 ] + F [ 3 ] * C(3, 5) * F [ 8 ] + F [ 3 ] * C(3, 1) * F [ 1 ] + F [ 3 ] * C(3, 3) * F [ 3 ] + S [ 1 ];
453 answer(1, 2) = F [ 8 ] * C(5, 4) * F [ 7 ] + F [ 8 ] * C(5, 3) * F [ 6 ] + F [ 8 ] * C(5, 2) * F [ 2 ] + F [ 1 ] * C(1, 4) * F [ 7 ] + F [ 1 ] * C(1, 3) * F [ 6 ] + F [ 1 ] * C(1, 2) * F [ 2 ] + F [ 3 ] * C(3, 4) * F [ 7 ] + F [ 3 ] * C(3, 3) * F [ 6 ] + F [ 3 ] * C(3, 2) * F [ 2 ] + 0.0;
454 answer(1, 3) = F [ 8 ] * C(5, 4) * F [ 8 ] + F [ 8 ] * C(5, 3) * F [ 1 ] + F [ 8 ] * C(5, 2) * F [ 3 ] + F [ 1 ] * C(1, 4) * F [ 8 ] + F [ 1 ] * C(1, 3) * F [ 1 ] + F [ 1 ] * C(1, 2) * F [ 3 ] + F [ 3 ] * C(3, 4) * F [ 8 ] + F [ 3 ] * C(3, 3) * F [ 1 ] + F [ 3 ] * C(3, 2) * F [ 3 ] + S [ 3 ];
455 answer(1, 4) = F [ 8 ] * C(5, 4) * F [ 0 ] + F [ 8 ] * C(5, 3) * F [ 5 ] + F [ 8 ] * C(5, 2) * F [ 4 ] + F [ 1 ] * C(1, 4) * F [ 0 ] + F [ 1 ] * C(1, 3) * F [ 5 ] + F [ 1 ] * C(1, 2) * F [ 4 ] + F [ 3 ] * C(3, 4) * F [ 0 ] + F [ 3 ] * C(3, 3) * F [ 5 ] + F [ 3 ] * C(3, 2) * F [ 4 ] + 0.0;
456 answer(1, 5) = F [ 8 ] * C(5, 5) * F [ 0 ] + F [ 8 ] * C(5, 1) * F [ 5 ] + F [ 8 ] * C(5, 3) * F [ 4 ] + F [ 1 ] * C(1, 5) * F [ 0 ] + F [ 1 ] * C(1, 1) * F [ 5 ] + F [ 1 ] * C(1, 3) * F [ 4 ] + F [ 3 ] * C(3, 5) * F [ 0 ] + F [ 3 ] * C(3, 1) * F [ 5 ] + F [ 3 ] * C(3, 3) * F [ 4 ] + 0.0;
457 answer(1, 6) = F [ 8 ] * C(5, 5) * F [ 7 ] + F [ 8 ] * C(5, 1) * F [ 6 ] + F [ 8 ] * C(5, 3) * F [ 2 ] + F [ 1 ] * C(1, 5) * F [ 7 ] + F [ 1 ] * C(1, 1) * F [ 6 ] + F [ 1 ] * C(1, 3) * F [ 2 ] + F [ 3 ] * C(3, 5) * F [ 7 ] + F [ 3 ] * C(3, 1) * F [ 6 ] + F [ 3 ] * C(3, 3) * F [ 2 ] + 0.0;
458 answer(1, 7) = F [ 8 ] * C(5, 0) * F [ 7 ] + F [ 8 ] * C(5, 5) * F [ 6 ] + F [ 8 ] * C(5, 4) * F [ 2 ] + F [ 1 ] * C(1, 0) * F [ 7 ] + F [ 1 ] * C(1, 5) * F [ 6 ] + F [ 1 ] * C(1, 4) * F [ 2 ] + F [ 3 ] * C(3, 0) * F [ 7 ] + F [ 3 ] * C(3, 5) * F [ 6 ] + F [ 3 ] * C(3, 4) * F [ 2 ] + 0.0;
459 answer(1, 8) = F [ 8 ] * C(5, 0) * F [ 8 ] + F [ 8 ] * C(5, 5) * F [ 1 ] + F [ 8 ] * C(5, 4) * F [ 3 ] + F [ 1 ] * C(1, 0) * F [ 8 ] + F [ 1 ] * C(1, 5) * F [ 1 ] + F [ 1 ] * C(1, 4) * F [ 3 ] + F [ 3 ] * C(3, 0) * F [ 8 ] + F [ 3 ] * C(3, 5) * F [ 1 ] + F [ 3 ] * C(3, 4) * F [ 3 ] + S [ 5 ];
460 answer(2, 0) = F [ 7 ] * C(4, 0) * F [ 0 ] + F [ 7 ] * C(4, 5) * F [ 5 ] + F [ 7 ] * C(4, 4) * F [ 4 ] + F [ 6 ] * C(3, 0) * F [ 0 ] + F [ 6 ] * C(3, 5) * F [ 5 ] + F [ 6 ] * C(3, 4) * F [ 4 ] + F [ 2 ] * C(2, 0) * F [ 0 ] + F [ 2 ] * C(2, 5) * F [ 5 ] + F [ 2 ] * C(2, 4) * F [ 4 ] + 0.0;
461 answer(2, 1) = F [ 7 ] * C(4, 5) * F [ 8 ] + F [ 7 ] * C(4, 1) * F [ 1 ] + F [ 7 ] * C(4, 3) * F [ 3 ] + F [ 6 ] * C(3, 5) * F [ 8 ] + F [ 6 ] * C(3, 1) * F [ 1 ] + F [ 6 ] * C(3, 3) * F [ 3 ] + F [ 2 ] * C(2, 5) * F [ 8 ] + F [ 2 ] * C(2, 1) * F [ 1 ] + F [ 2 ] * C(2, 3) * F [ 3 ] + 0.0;
462 answer(2, 2) = F [ 7 ] * C(4, 4) * F [ 7 ] + F [ 7 ] * C(4, 3) * F [ 6 ] + F [ 7 ] * C(4, 2) * F [ 2 ] + F [ 6 ] * C(3, 4) * F [ 7 ] + F [ 6 ] * C(3, 3) * F [ 6 ] + F [ 6 ] * C(3, 2) * F [ 2 ] + F [ 2 ] * C(2, 4) * F [ 7 ] + F [ 2 ] * C(2, 3) * F [ 6 ] + F [ 2 ] * C(2, 2) * F [ 2 ] + S [ 2 ];
463 answer(2, 3) = F [ 7 ] * C(4, 4) * F [ 8 ] + F [ 7 ] * C(4, 3) * F [ 1 ] + F [ 7 ] * C(4, 2) * F [ 3 ] + F [ 6 ] * C(3, 4) * F [ 8 ] + F [ 6 ] * C(3, 3) * F [ 1 ] + F [ 6 ] * C(3, 2) * F [ 3 ] + F [ 2 ] * C(2, 4) * F [ 8 ] + F [ 2 ] * C(2, 3) * F [ 1 ] + F [ 2 ] * C(2, 2) * F [ 3 ] + 0.0;
464 answer(2, 4) = F [ 7 ] * C(4, 4) * F [ 0 ] + F [ 7 ] * C(4, 3) * F [ 5 ] + F [ 7 ] * C(4, 2) * F [ 4 ] + F [ 6 ] * C(3, 4) * F [ 0 ] + F [ 6 ] * C(3, 3) * F [ 5 ] + F [ 6 ] * C(3, 2) * F [ 4 ] + F [ 2 ] * C(2, 4) * F [ 0 ] + F [ 2 ] * C(2, 3) * F [ 5 ] + F [ 2 ] * C(2, 2) * F [ 4 ] + 0.0;
465 answer(2, 5) = F [ 7 ] * C(4, 5) * F [ 0 ] + F [ 7 ] * C(4, 1) * F [ 5 ] + F [ 7 ] * C(4, 3) * F [ 4 ] + F [ 6 ] * C(3, 5) * F [ 0 ] + F [ 6 ] * C(3, 1) * F [ 5 ] + F [ 6 ] * C(3, 3) * F [ 4 ] + F [ 2 ] * C(2, 5) * F [ 0 ] + F [ 2 ] * C(2, 1) * F [ 5 ] + F [ 2 ] * C(2, 3) * F [ 4 ] + 0.0;
466 answer(2, 6) = F [ 7 ] * C(4, 5) * F [ 7 ] + F [ 7 ] * C(4, 1) * F [ 6 ] + F [ 7 ] * C(4, 3) * F [ 2 ] + F [ 6 ] * C(3, 5) * F [ 7 ] + F [ 6 ] * C(3, 1) * F [ 6 ] + F [ 6 ] * C(3, 3) * F [ 2 ] + F [ 2 ] * C(2, 5) * F [ 7 ] + F [ 2 ] * C(2, 1) * F [ 6 ] + F [ 2 ] * C(2, 3) * F [ 2 ] + S [ 3 ];
467 answer(2, 7) = F [ 7 ] * C(4, 0) * F [ 7 ] + F [ 7 ] * C(4, 5) * F [ 6 ] + F [ 7 ] * C(4, 4) * F [ 2 ] + F [ 6 ] * C(3, 0) * F [ 7 ] + F [ 6 ] * C(3, 5) * F [ 6 ] + F [ 6 ] * C(3, 4) * F [ 2 ] + F [ 2 ] * C(2, 0) * F [ 7 ] + F [ 2 ] * C(2, 5) * F [ 6 ] + F [ 2 ] * C(2, 4) * F [ 2 ] + S [ 4 ];
468 answer(2, 8) = F [ 7 ] * C(4, 0) * F [ 8 ] + F [ 7 ] * C(4, 5) * F [ 1 ] + F [ 7 ] * C(4, 4) * F [ 3 ] + F [ 6 ] * C(3, 0) * F [ 8 ] + F [ 6 ] * C(3, 5) * F [ 1 ] + F [ 6 ] * C(3, 4) * F [ 3 ] + F [ 2 ] * C(2, 0) * F [ 8 ] + F [ 2 ] * C(2, 5) * F [ 1 ] + F [ 2 ] * C(2, 4) * F [ 3 ] + 0.0;
469 answer(3, 0) = F [ 8 ] * C(4, 0) * F [ 0 ] + F [ 8 ] * C(4, 5) * F [ 5 ] + F [ 8 ] * C(4, 4) * F [ 4 ] + F [ 1 ] * C(3, 0) * F [ 0 ] + F [ 1 ] * C(3, 5) * F [ 5 ] + F [ 1 ] * C(3, 4) * F [ 4 ] + F [ 3 ] * C(2, 0) * F [ 0 ] + F [ 3 ] * C(2, 5) * F [ 5 ] + F [ 3 ] * C(2, 4) * F [ 4 ] + 0.0;
470 answer(3, 1) = F [ 8 ] * C(4, 5) * F [ 8 ] + F [ 8 ] * C(4, 1) * F [ 1 ] + F [ 8 ] * C(4, 3) * F [ 3 ] + F [ 1 ] * C(3, 5) * F [ 8 ] + F [ 1 ] * C(3, 1) * F [ 1 ] + F [ 1 ] * C(3, 3) * F [ 3 ] + F [ 3 ] * C(2, 5) * F [ 8 ] + F [ 3 ] * C(2, 1) * F [ 1 ] + F [ 3 ] * C(2, 3) * F [ 3 ] + S [ 3 ];
471 answer(3, 2) = F [ 8 ] * C(4, 4) * F [ 7 ] + F [ 8 ] * C(4, 3) * F [ 6 ] + F [ 8 ] * C(4, 2) * F [ 2 ] + F [ 1 ] * C(3, 4) * F [ 7 ] + F [ 1 ] * C(3, 3) * F [ 6 ] + F [ 1 ] * C(3, 2) * F [ 2 ] + F [ 3 ] * C(2, 4) * F [ 7 ] + F [ 3 ] * C(2, 3) * F [ 6 ] + F [ 3 ] * C(2, 2) * F [ 2 ] + 0.0;
472 answer(3, 3) = F [ 8 ] * C(4, 4) * F [ 8 ] + F [ 8 ] * C(4, 3) * F [ 1 ] + F [ 8 ] * C(4, 2) * F [ 3 ] + F [ 1 ] * C(3, 4) * F [ 8 ] + F [ 1 ] * C(3, 3) * F [ 1 ] + F [ 1 ] * C(3, 2) * F [ 3 ] + F [ 3 ] * C(2, 4) * F [ 8 ] + F [ 3 ] * C(2, 3) * F [ 1 ] + F [ 3 ] * C(2, 2) * F [ 3 ] + S [ 2 ];
473 answer(3, 4) = F [ 8 ] * C(4, 4) * F [ 0 ] + F [ 8 ] * C(4, 3) * F [ 5 ] + F [ 8 ] * C(4, 2) * F [ 4 ] + F [ 1 ] * C(3, 4) * F [ 0 ] + F [ 1 ] * C(3, 3) * F [ 5 ] + F [ 1 ] * C(3, 2) * F [ 4 ] + F [ 3 ] * C(2, 4) * F [ 0 ] + F [ 3 ] * C(2, 3) * F [ 5 ] + F [ 3 ] * C(2, 2) * F [ 4 ] + 0.0;
474 answer(3, 5) = F [ 8 ] * C(4, 5) * F [ 0 ] + F [ 8 ] * C(4, 1) * F [ 5 ] + F [ 8 ] * C(4, 3) * F [ 4 ] + F [ 1 ] * C(3, 5) * F [ 0 ] + F [ 1 ] * C(3, 1) * F [ 5 ] + F [ 1 ] * C(3, 3) * F [ 4 ] + F [ 3 ] * C(2, 5) * F [ 0 ] + F [ 3 ] * C(2, 1) * F [ 5 ] + F [ 3 ] * C(2, 3) * F [ 4 ] + 0.0;
475 answer(3, 6) = F [ 8 ] * C(4, 5) * F [ 7 ] + F [ 8 ] * C(4, 1) * F [ 6 ] + F [ 8 ] * C(4, 3) * F [ 2 ] + F [ 1 ] * C(3, 5) * F [ 7 ] + F [ 1 ] * C(3, 1) * F [ 6 ] + F [ 1 ] * C(3, 3) * F [ 2 ] + F [ 3 ] * C(2, 5) * F [ 7 ] + F [ 3 ] * C(2, 1) * F [ 6 ] + F [ 3 ] * C(2, 3) * F [ 2 ] + 0.0;
476 answer(3, 7) = F [ 8 ] * C(4, 0) * F [ 7 ] + F [ 8 ] * C(4, 5) * F [ 6 ] + F [ 8 ] * C(4, 4) * F [ 2 ] + F [ 1 ] * C(3, 0) * F [ 7 ] + F [ 1 ] * C(3, 5) * F [ 6 ] + F [ 1 ] * C(3, 4) * F [ 2 ] + F [ 3 ] * C(2, 0) * F [ 7 ] + F [ 3 ] * C(2, 5) * F [ 6 ] + F [ 3 ] * C(2, 4) * F [ 2 ] + 0.0;
477 answer(3, 8) = F [ 8 ] * C(4, 0) * F [ 8 ] + F [ 8 ] * C(4, 5) * F [ 1 ] + F [ 8 ] * C(4, 4) * F [ 3 ] + F [ 1 ] * C(3, 0) * F [ 8 ] + F [ 1 ] * C(3, 5) * F [ 1 ] + F [ 1 ] * C(3, 4) * F [ 3 ] + F [ 3 ] * C(2, 0) * F [ 8 ] + F [ 3 ] * C(2, 5) * F [ 1 ] + F [ 3 ] * C(2, 4) * F [ 3 ] + S [ 4 ];
478 answer(4, 0) = F [ 0 ] * C(4, 0) * F [ 0 ] + F [ 0 ] * C(4, 5) * F [ 5 ] + F [ 0 ] * C(4, 4) * F [ 4 ] + F [ 5 ] * C(3, 0) * F [ 0 ] + F [ 5 ] * C(3, 5) * F [ 5 ] + F [ 5 ] * C(3, 4) * F [ 4 ] + F [ 4 ] * C(2, 0) * F [ 0 ] + F [ 4 ] * C(2, 5) * F [ 5 ] + F [ 4 ] * C(2, 4) * F [ 4 ] + S [ 4 ];
479 answer(4, 1) = F [ 0 ] * C(4, 5) * F [ 8 ] + F [ 0 ] * C(4, 1) * F [ 1 ] + F [ 0 ] * C(4, 3) * F [ 3 ] + F [ 5 ] * C(3, 5) * F [ 8 ] + F [ 5 ] * C(3, 1) * F [ 1 ] + F [ 5 ] * C(3, 3) * F [ 3 ] + F [ 4 ] * C(2, 5) * F [ 8 ] + F [ 4 ] * C(2, 1) * F [ 1 ] + F [ 4 ] * C(2, 3) * F [ 3 ] + 0.0;
480 answer(4, 2) = F [ 0 ] * C(4, 4) * F [ 7 ] + F [ 0 ] * C(4, 3) * F [ 6 ] + F [ 0 ] * C(4, 2) * F [ 2 ] + F [ 5 ] * C(3, 4) * F [ 7 ] + F [ 5 ] * C(3, 3) * F [ 6 ] + F [ 5 ] * C(3, 2) * F [ 2 ] + F [ 4 ] * C(2, 4) * F [ 7 ] + F [ 4 ] * C(2, 3) * F [ 6 ] + F [ 4 ] * C(2, 2) * F [ 2 ] + 0.0;
481 answer(4, 3) = F [ 0 ] * C(4, 4) * F [ 8 ] + F [ 0 ] * C(4, 3) * F [ 1 ] + F [ 0 ] * C(4, 2) * F [ 3 ] + F [ 5 ] * C(3, 4) * F [ 8 ] + F [ 5 ] * C(3, 3) * F [ 1 ] + F [ 5 ] * C(3, 2) * F [ 3 ] + F [ 4 ] * C(2, 4) * F [ 8 ] + F [ 4 ] * C(2, 3) * F [ 1 ] + F [ 4 ] * C(2, 2) * F [ 3 ] + 0.0;
482 answer(4, 4) = F [ 0 ] * C(4, 4) * F [ 0 ] + F [ 0 ] * C(4, 3) * F [ 5 ] + F [ 0 ] * C(4, 2) * F [ 4 ] + F [ 5 ] * C(3, 4) * F [ 0 ] + F [ 5 ] * C(3, 3) * F [ 5 ] + F [ 5 ] * C(3, 2) * F [ 4 ] + F [ 4 ] * C(2, 4) * F [ 0 ] + F [ 4 ] * C(2, 3) * F [ 5 ] + F [ 4 ] * C(2, 2) * F [ 4 ] + S [ 2 ];
483 answer(4, 5) = F [ 0 ] * C(4, 5) * F [ 0 ] + F [ 0 ] * C(4, 1) * F [ 5 ] + F [ 0 ] * C(4, 3) * F [ 4 ] + F [ 5 ] * C(3, 5) * F [ 0 ] + F [ 5 ] * C(3, 1) * F [ 5 ] + F [ 5 ] * C(3, 3) * F [ 4 ] + F [ 4 ] * C(2, 5) * F [ 0 ] + F [ 4 ] * C(2, 1) * F [ 5 ] + F [ 4 ] * C(2, 3) * F [ 4 ] + S [ 3 ];
484 answer(4, 6) = F [ 0 ] * C(4, 5) * F [ 7 ] + F [ 0 ] * C(4, 1) * F [ 6 ] + F [ 0 ] * C(4, 3) * F [ 2 ] + F [ 5 ] * C(3, 5) * F [ 7 ] + F [ 5 ] * C(3, 1) * F [ 6 ] + F [ 5 ] * C(3, 3) * F [ 2 ] + F [ 4 ] * C(2, 5) * F [ 7 ] + F [ 4 ] * C(2, 1) * F [ 6 ] + F [ 4 ] * C(2, 3) * F [ 2 ] + 0.0;
485 answer(4, 7) = F [ 0 ] * C(4, 0) * F [ 7 ] + F [ 0 ] * C(4, 5) * F [ 6 ] + F [ 0 ] * C(4, 4) * F [ 2 ] + F [ 5 ] * C(3, 0) * F [ 7 ] + F [ 5 ] * C(3, 5) * F [ 6 ] + F [ 5 ] * C(3, 4) * F [ 2 ] + F [ 4 ] * C(2, 0) * F [ 7 ] + F [ 4 ] * C(2, 5) * F [ 6 ] + F [ 4 ] * C(2, 4) * F [ 2 ] + 0.0;
486 answer(4, 8) = F [ 0 ] * C(4, 0) * F [ 8 ] + F [ 0 ] * C(4, 5) * F [ 1 ] + F [ 0 ] * C(4, 4) * F [ 3 ] + F [ 5 ] * C(3, 0) * F [ 8 ] + F [ 5 ] * C(3, 5) * F [ 1 ] + F [ 5 ] * C(3, 4) * F [ 3 ] + F [ 4 ] * C(2, 0) * F [ 8 ] + F [ 4 ] * C(2, 5) * F [ 1 ] + F [ 4 ] * C(2, 4) * F [ 3 ] + 0.0;
487 answer(5, 0) = F [ 0 ] * C(5, 0) * F [ 0 ] + F [ 0 ] * C(5, 5) * F [ 5 ] + F [ 0 ] * C(5, 4) * F [ 4 ] + F [ 5 ] * C(1, 0) * F [ 0 ] + F [ 5 ] * C(1, 5) * F [ 5 ] + F [ 5 ] * C(1, 4) * F [ 4 ] + F [ 4 ] * C(3, 0) * F [ 0 ] + F [ 4 ] * C(3, 5) * F [ 5 ] + F [ 4 ] * C(3, 4) * F [ 4 ] + S [ 5 ];
488 answer(5, 1) = F [ 0 ] * C(5, 5) * F [ 8 ] + F [ 0 ] * C(5, 1) * F [ 1 ] + F [ 0 ] * C(5, 3) * F [ 3 ] + F [ 5 ] * C(1, 5) * F [ 8 ] + F [ 5 ] * C(1, 1) * F [ 1 ] + F [ 5 ] * C(1, 3) * F [ 3 ] + F [ 4 ] * C(3, 5) * F [ 8 ] + F [ 4 ] * C(3, 1) * F [ 1 ] + F [ 4 ] * C(3, 3) * F [ 3 ] + 0.0;
489 answer(5, 2) = F [ 0 ] * C(5, 4) * F [ 7 ] + F [ 0 ] * C(5, 3) * F [ 6 ] + F [ 0 ] * C(5, 2) * F [ 2 ] + F [ 5 ] * C(1, 4) * F [ 7 ] + F [ 5 ] * C(1, 3) * F [ 6 ] + F [ 5 ] * C(1, 2) * F [ 2 ] + F [ 4 ] * C(3, 4) * F [ 7 ] + F [ 4 ] * C(3, 3) * F [ 6 ] + F [ 4 ] * C(3, 2) * F [ 2 ] + 0.0;
490 answer(5, 3) = F [ 0 ] * C(5, 4) * F [ 8 ] + F [ 0 ] * C(5, 3) * F [ 1 ] + F [ 0 ] * C(5, 2) * F [ 3 ] + F [ 5 ] * C(1, 4) * F [ 8 ] + F [ 5 ] * C(1, 3) * F [ 1 ] + F [ 5 ] * C(1, 2) * F [ 3 ] + F [ 4 ] * C(3, 4) * F [ 8 ] + F [ 4 ] * C(3, 3) * F [ 1 ] + F [ 4 ] * C(3, 2) * F [ 3 ] + 0.0;
491 answer(5, 4) = F [ 0 ] * C(5, 4) * F [ 0 ] + F [ 0 ] * C(5, 3) * F [ 5 ] + F [ 0 ] * C(5, 2) * F [ 4 ] + F [ 5 ] * C(1, 4) * F [ 0 ] + F [ 5 ] * C(1, 3) * F [ 5 ] + F [ 5 ] * C(1, 2) * F [ 4 ] + F [ 4 ] * C(3, 4) * F [ 0 ] + F [ 4 ] * C(3, 3) * F [ 5 ] + F [ 4 ] * C(3, 2) * F [ 4 ] + S [ 3 ];
492 answer(5, 5) = F [ 0 ] * C(5, 5) * F [ 0 ] + F [ 0 ] * C(5, 1) * F [ 5 ] + F [ 0 ] * C(5, 3) * F [ 4 ] + F [ 5 ] * C(1, 5) * F [ 0 ] + F [ 5 ] * C(1, 1) * F [ 5 ] + F [ 5 ] * C(1, 3) * F [ 4 ] + F [ 4 ] * C(3, 5) * F [ 0 ] + F [ 4 ] * C(3, 1) * F [ 5 ] + F [ 4 ] * C(3, 3) * F [ 4 ] + S [ 1 ];
493 answer(5, 6) = F [ 0 ] * C(5, 5) * F [ 7 ] + F [ 0 ] * C(5, 1) * F [ 6 ] + F [ 0 ] * C(5, 3) * F [ 2 ] + F [ 5 ] * C(1, 5) * F [ 7 ] + F [ 5 ] * C(1, 1) * F [ 6 ] + F [ 5 ] * C(1, 3) * F [ 2 ] + F [ 4 ] * C(3, 5) * F [ 7 ] + F [ 4 ] * C(3, 1) * F [ 6 ] + F [ 4 ] * C(3, 3) * F [ 2 ] + 0.0;
494 answer(5, 7) = F [ 0 ] * C(5, 0) * F [ 7 ] + F [ 0 ] * C(5, 5) * F [ 6 ] + F [ 0 ] * C(5, 4) * F [ 2 ] + F [ 5 ] * C(1, 0) * F [ 7 ] + F [ 5 ] * C(1, 5) * F [ 6 ] + F [ 5 ] * C(1, 4) * F [ 2 ] + F [ 4 ] * C(3, 0) * F [ 7 ] + F [ 4 ] * C(3, 5) * F [ 6 ] + F [ 4 ] * C(3, 4) * F [ 2 ] + 0.0;
495 answer(5, 8) = F [ 0 ] * C(5, 0) * F [ 8 ] + F [ 0 ] * C(5, 5) * F [ 1 ] + F [ 0 ] * C(5, 4) * F [ 3 ] + F [ 5 ] * C(1, 0) * F [ 8 ] + F [ 5 ] * C(1, 5) * F [ 1 ] + F [ 5 ] * C(1, 4) * F [ 3 ] + F [ 4 ] * C(3, 0) * F [ 8 ] + F [ 4 ] * C(3, 5) * F [ 1 ] + F [ 4 ] * C(3, 4) * F [ 3 ] + 0.0;
496 answer(6, 0) = F [ 7 ] * C(5, 0) * F [ 0 ] + F [ 7 ] * C(5, 5) * F [ 5 ] + F [ 7 ] * C(5, 4) * F [ 4 ] + F [ 6 ] * C(1, 0) * F [ 0 ] + F [ 6 ] * C(1, 5) * F [ 5 ] + F [ 6 ] * C(1, 4) * F [ 4 ] + F [ 2 ] * C(3, 0) * F [ 0 ] + F [ 2 ] * C(3, 5) * F [ 5 ] + F [ 2 ] * C(3, 4) * F [ 4 ] + 0.0;
497 answer(6, 1) = F [ 7 ] * C(5, 5) * F [ 8 ] + F [ 7 ] * C(5, 1) * F [ 1 ] + F [ 7 ] * C(5, 3) * F [ 3 ] + F [ 6 ] * C(1, 5) * F [ 8 ] + F [ 6 ] * C(1, 1) * F [ 1 ] + F [ 6 ] * C(1, 3) * F [ 3 ] + F [ 2 ] * C(3, 5) * F [ 8 ] + F [ 2 ] * C(3, 1) * F [ 1 ] + F [ 2 ] * C(3, 3) * F [ 3 ] + 0.0;
498 answer(6, 2) = F [ 7 ] * C(5, 4) * F [ 7 ] + F [ 7 ] * C(5, 3) * F [ 6 ] + F [ 7 ] * C(5, 2) * F [ 2 ] + F [ 6 ] * C(1, 4) * F [ 7 ] + F [ 6 ] * C(1, 3) * F [ 6 ] + F [ 6 ] * C(1, 2) * F [ 2 ] + F [ 2 ] * C(3, 4) * F [ 7 ] + F [ 2 ] * C(3, 3) * F [ 6 ] + F [ 2 ] * C(3, 2) * F [ 2 ] + S [ 3 ];
499 answer(6, 3) = F [ 7 ] * C(5, 4) * F [ 8 ] + F [ 7 ] * C(5, 3) * F [ 1 ] + F [ 7 ] * C(5, 2) * F [ 3 ] + F [ 6 ] * C(1, 4) * F [ 8 ] + F [ 6 ] * C(1, 3) * F [ 1 ] + F [ 6 ] * C(1, 2) * F [ 3 ] + F [ 2 ] * C(3, 4) * F [ 8 ] + F [ 2 ] * C(3, 3) * F [ 1 ] + F [ 2 ] * C(3, 2) * F [ 3 ] + 0.0;
500 answer(6, 4) = F [ 7 ] * C(5, 4) * F [ 0 ] + F [ 7 ] * C(5, 3) * F [ 5 ] + F [ 7 ] * C(5, 2) * F [ 4 ] + F [ 6 ] * C(1, 4) * F [ 0 ] + F [ 6 ] * C(1, 3) * F [ 5 ] + F [ 6 ] * C(1, 2) * F [ 4 ] + F [ 2 ] * C(3, 4) * F [ 0 ] + F [ 2 ] * C(3, 3) * F [ 5 ] + F [ 2 ] * C(3, 2) * F [ 4 ] + 0.0;
501 answer(6, 5) = F [ 7 ] * C(5, 5) * F [ 0 ] + F [ 7 ] * C(5, 1) * F [ 5 ] + F [ 7 ] * C(5, 3) * F [ 4 ] + F [ 6 ] * C(1, 5) * F [ 0 ] + F [ 6 ] * C(1, 1) * F [ 5 ] + F [ 6 ] * C(1, 3) * F [ 4 ] + F [ 2 ] * C(3, 5) * F [ 0 ] + F [ 2 ] * C(3, 1) * F [ 5 ] + F [ 2 ] * C(3, 3) * F [ 4 ] + 0.0;
502 answer(6, 6) = F [ 7 ] * C(5, 5) * F [ 7 ] + F [ 7 ] * C(5, 1) * F [ 6 ] + F [ 7 ] * C(5, 3) * F [ 2 ] + F [ 6 ] * C(1, 5) * F [ 7 ] + F [ 6 ] * C(1, 1) * F [ 6 ] + F [ 6 ] * C(1, 3) * F [ 2 ] + F [ 2 ] * C(3, 5) * F [ 7 ] + F [ 2 ] * C(3, 1) * F [ 6 ] + F [ 2 ] * C(3, 3) * F [ 2 ] + S [ 1 ];
503 answer(6, 7) = F [ 7 ] * C(5, 0) * F [ 7 ] + F [ 7 ] * C(5, 5) * F [ 6 ] + F [ 7 ] * C(5, 4) * F [ 2 ] + F [ 6 ] * C(1, 0) * F [ 7 ] + F [ 6 ] * C(1, 5) * F [ 6 ] + F [ 6 ] * C(1, 4) * F [ 2 ] + F [ 2 ] * C(3, 0) * F [ 7 ] + F [ 2 ] * C(3, 5) * F [ 6 ] + F [ 2 ] * C(3, 4) * F [ 2 ] + S [ 5 ];
504 answer(6, 8) = F [ 7 ] * C(5, 0) * F [ 8 ] + F [ 7 ] * C(5, 5) * F [ 1 ] + F [ 7 ] * C(5, 4) * F [ 3 ] + F [ 6 ] * C(1, 0) * F [ 8 ] + F [ 6 ] * C(1, 5) * F [ 1 ] + F [ 6 ] * C(1, 4) * F [ 3 ] + F [ 2 ] * C(3, 0) * F [ 8 ] + F [ 2 ] * C(3, 5) * F [ 1 ] + F [ 2 ] * C(3, 4) * F [ 3 ] + 0.0;
505 answer(7, 0) = F [ 7 ] * C(0, 0) * F [ 0 ] + F [ 7 ] * C(0, 5) * F [ 5 ] + F [ 7 ] * C(0, 4) * F [ 4 ] + F [ 6 ] * C(5, 0) * F [ 0 ] + F [ 6 ] * C(5, 5) * F [ 5 ] + F [ 6 ] * C(5, 4) * F [ 4 ] + F [ 2 ] * C(4, 0) * F [ 0 ] + F [ 2 ] * C(4, 5) * F [ 5 ] + F [ 2 ] * C(4, 4) * F [ 4 ] + 0.0;
506 answer(7, 1) = F [ 7 ] * C(0, 5) * F [ 8 ] + F [ 7 ] * C(0, 1) * F [ 1 ] + F [ 7 ] * C(0, 3) * F [ 3 ] + F [ 6 ] * C(5, 5) * F [ 8 ] + F [ 6 ] * C(5, 1) * F [ 1 ] + F [ 6 ] * C(5, 3) * F [ 3 ] + F [ 2 ] * C(4, 5) * F [ 8 ] + F [ 2 ] * C(4, 1) * F [ 1 ] + F [ 2 ] * C(4, 3) * F [ 3 ] + 0.0;
507 answer(7, 2) = F [ 7 ] * C(0, 4) * F [ 7 ] + F [ 7 ] * C(0, 3) * F [ 6 ] + F [ 7 ] * C(0, 2) * F [ 2 ] + F [ 6 ] * C(5, 4) * F [ 7 ] + F [ 6 ] * C(5, 3) * F [ 6 ] + F [ 6 ] * C(5, 2) * F [ 2 ] + F [ 2 ] * C(4, 4) * F [ 7 ] + F [ 2 ] * C(4, 3) * F [ 6 ] + F [ 2 ] * C(4, 2) * F [ 2 ] + S [ 4 ];
508 answer(7, 3) = F [ 7 ] * C(0, 4) * F [ 8 ] + F [ 7 ] * C(0, 3) * F [ 1 ] + F [ 7 ] * C(0, 2) * F [ 3 ] + F [ 6 ] * C(5, 4) * F [ 8 ] + F [ 6 ] * C(5, 3) * F [ 1 ] + F [ 6 ] * C(5, 2) * F [ 3 ] + F [ 2 ] * C(4, 4) * F [ 8 ] + F [ 2 ] * C(4, 3) * F [ 1 ] + F [ 2 ] * C(4, 2) * F [ 3 ] + 0.0;
509 answer(7, 4) = F [ 7 ] * C(0, 4) * F [ 0 ] + F [ 7 ] * C(0, 3) * F [ 5 ] + F [ 7 ] * C(0, 2) * F [ 4 ] + F [ 6 ] * C(5, 4) * F [ 0 ] + F [ 6 ] * C(5, 3) * F [ 5 ] + F [ 6 ] * C(5, 2) * F [ 4 ] + F [ 2 ] * C(4, 4) * F [ 0 ] + F [ 2 ] * C(4, 3) * F [ 5 ] + F [ 2 ] * C(4, 2) * F [ 4 ] + 0.0;
510 answer(7, 5) = F [ 7 ] * C(0, 5) * F [ 0 ] + F [ 7 ] * C(0, 1) * F [ 5 ] + F [ 7 ] * C(0, 3) * F [ 4 ] + F [ 6 ] * C(5, 5) * F [ 0 ] + F [ 6 ] * C(5, 1) * F [ 5 ] + F [ 6 ] * C(5, 3) * F [ 4 ] + F [ 2 ] * C(4, 5) * F [ 0 ] + F [ 2 ] * C(4, 1) * F [ 5 ] + F [ 2 ] * C(4, 3) * F [ 4 ] + 0.0;
511 answer(7, 6) = F [ 7 ] * C(0, 5) * F [ 7 ] + F [ 7 ] * C(0, 1) * F [ 6 ] + F [ 7 ] * C(0, 3) * F [ 2 ] + F [ 6 ] * C(5, 5) * F [ 7 ] + F [ 6 ] * C(5, 1) * F [ 6 ] + F [ 6 ] * C(5, 3) * F [ 2 ] + F [ 2 ] * C(4, 5) * F [ 7 ] + F [ 2 ] * C(4, 1) * F [ 6 ] + F [ 2 ] * C(4, 3) * F [ 2 ] + S [ 5 ];
512 answer(7, 7) = F [ 7 ] * C(0, 0) * F [ 7 ] + F [ 7 ] * C(0, 5) * F [ 6 ] + F [ 7 ] * C(0, 4) * F [ 2 ] + F [ 6 ] * C(5, 0) * F [ 7 ] + F [ 6 ] * C(5, 5) * F [ 6 ] + F [ 6 ] * C(5, 4) * F [ 2 ] + F [ 2 ] * C(4, 0) * F [ 7 ] + F [ 2 ] * C(4, 5) * F [ 6 ] + F [ 2 ] * C(4, 4) * F [ 2 ] + S [ 0 ];
513 answer(7, 8) = F [ 7 ] * C(0, 0) * F [ 8 ] + F [ 7 ] * C(0, 5) * F [ 1 ] + F [ 7 ] * C(0, 4) * F [ 3 ] + F [ 6 ] * C(5, 0) * F [ 8 ] + F [ 6 ] * C(5, 5) * F [ 1 ] + F [ 6 ] * C(5, 4) * F [ 3 ] + F [ 2 ] * C(4, 0) * F [ 8 ] + F [ 2 ] * C(4, 5) * F [ 1 ] + F [ 2 ] * C(4, 4) * F [ 3 ] + 0.0;
514 answer(8, 0) = F [ 8 ] * C(0, 0) * F [ 0 ] + F [ 8 ] * C(0, 5) * F [ 5 ] + F [ 8 ] * C(0, 4) * F [ 4 ] + F [ 1 ] * C(5, 0) * F [ 0 ] + F [ 1 ] * C(5, 5) * F [ 5 ] + F [ 1 ] * C(5, 4) * F [ 4 ] + F [ 3 ] * C(4, 0) * F [ 0 ] + F [ 3 ] * C(4, 5) * F [ 5 ] + F [ 3 ] * C(4, 4) * F [ 4 ] + 0.0;
515 answer(8, 1) = F [ 8 ] * C(0, 5) * F [ 8 ] + F [ 8 ] * C(0, 1) * F [ 1 ] + F [ 8 ] * C(0, 3) * F [ 3 ] + F [ 1 ] * C(5, 5) * F [ 8 ] + F [ 1 ] * C(5, 1) * F [ 1 ] + F [ 1 ] * C(5, 3) * F [ 3 ] + F [ 3 ] * C(4, 5) * F [ 8 ] + F [ 3 ] * C(4, 1) * F [ 1 ] + F [ 3 ] * C(4, 3) * F [ 3 ] + S [ 5 ];
516 answer(8, 2) = F [ 8 ] * C(0, 4) * F [ 7 ] + F [ 8 ] * C(0, 3) * F [ 6 ] + F [ 8 ] * C(0, 2) * F [ 2 ] + F [ 1 ] * C(5, 4) * F [ 7 ] + F [ 1 ] * C(5, 3) * F [ 6 ] + F [ 1 ] * C(5, 2) * F [ 2 ] + F [ 3 ] * C(4, 4) * F [ 7 ] + F [ 3 ] * C(4, 3) * F [ 6 ] + F [ 3 ] * C(4, 2) * F [ 2 ] + 0.0;
517 answer(8, 3) = F [ 8 ] * C(0, 4) * F [ 8 ] + F [ 8 ] * C(0, 3) * F [ 1 ] + F [ 8 ] * C(0, 2) * F [ 3 ] + F [ 1 ] * C(5, 4) * F [ 8 ] + F [ 1 ] * C(5, 3) * F [ 1 ] + F [ 1 ] * C(5, 2) * F [ 3 ] + F [ 3 ] * C(4, 4) * F [ 8 ] + F [ 3 ] * C(4, 3) * F [ 1 ] + F [ 3 ] * C(4, 2) * F [ 3 ] + S [ 4 ];
518 answer(8, 4) = F [ 8 ] * C(0, 4) * F [ 0 ] + F [ 8 ] * C(0, 3) * F [ 5 ] + F [ 8 ] * C(0, 2) * F [ 4 ] + F [ 1 ] * C(5, 4) * F [ 0 ] + F [ 1 ] * C(5, 3) * F [ 5 ] + F [ 1 ] * C(5, 2) * F [ 4 ] + F [ 3 ] * C(4, 4) * F [ 0 ] + F [ 3 ] * C(4, 3) * F [ 5 ] + F [ 3 ] * C(4, 2) * F [ 4 ] + 0.0;
519 answer(8, 5) = F [ 8 ] * C(0, 5) * F [ 0 ] + F [ 8 ] * C(0, 1) * F [ 5 ] + F [ 8 ] * C(0, 3) * F [ 4 ] + F [ 1 ] * C(5, 5) * F [ 0 ] + F [ 1 ] * C(5, 1) * F [ 5 ] + F [ 1 ] * C(5, 3) * F [ 4 ] + F [ 3 ] * C(4, 5) * F [ 0 ] + F [ 3 ] * C(4, 1) * F [ 5 ] + F [ 3 ] * C(4, 3) * F [ 4 ] + 0.0;
520 answer(8, 6) = F [ 8 ] * C(0, 5) * F [ 7 ] + F [ 8 ] * C(0, 1) * F [ 6 ] + F [ 8 ] * C(0, 3) * F [ 2 ] + F [ 1 ] * C(5, 5) * F [ 7 ] + F [ 1 ] * C(5, 1) * F [ 6 ] + F [ 1 ] * C(5, 3) * F [ 2 ] + F [ 3 ] * C(4, 5) * F [ 7 ] + F [ 3 ] * C(4, 1) * F [ 6 ] + F [ 3 ] * C(4, 3) * F [ 2 ] + 0.0;
521 answer(8, 7) = F [ 8 ] * C(0, 0) * F [ 7 ] + F [ 8 ] * C(0, 5) * F [ 6 ] + F [ 8 ] * C(0, 4) * F [ 2 ] + F [ 1 ] * C(5, 0) * F [ 7 ] + F [ 1 ] * C(5, 5) * F [ 6 ] + F [ 1 ] * C(5, 4) * F [ 2 ] + F [ 3 ] * C(4, 0) * F [ 7 ] + F [ 3 ] * C(4, 5) * F [ 6 ] + F [ 3 ] * C(4, 4) * F [ 2 ] + 0.0;
522 answer(8, 8) = F [ 8 ] * C(0, 0) * F [ 8 ] + F [ 8 ] * C(0, 5) * F [ 1 ] + F [ 8 ] * C(0, 4) * F [ 3 ] + F [ 1 ] * C(5, 0) * F [ 8 ] + F [ 1 ] * C(5, 5) * F [ 1 ] + F [ 1 ] * C(5, 4) * F [ 3 ] + F [ 3 ] * C(4, 0) * F [ 8 ] + F [ 3 ] * C(4, 5) * F [ 1 ] + F [ 3 ] * C(4, 4) * F [ 3 ] + S [ 0 ];
523
524#else
526 // Conversion expressed in index form. Seems a tiny bit slower than that above but easier to debug.
527 auto I = eye< 3 >();
528
529 //I_ik * S_jl + F_im F_kn C_mjnl
530 for ( int i = 1; i <= 3; i++ ) {
531 for ( int j = 1; j <= 3; j++ ) {
532 for ( int k = 1; k <= 3; k++ ) {
533 for ( int l = 1; l <= 3; l++ ) {
534 for ( int m = 1; m <= 3; m++ ) {
535 for ( int n = 1; n <= 3; n++ ) {
536 answer.at(giveVI(i, j), giveVI(k, l) ) += I.at(i, k) * S.at(giveSymVI(j, l) ) + F.at(giveVI(i, m) ) * F.at(giveVI(k, n) ) * C.at(giveSymVI(m, j), giveSymVI(n, l) );
537 }
538 }
539 }
540 }
541 }
542 }
543#endif
544 return answer;
545}
546
549{
550 //Save terms associated with H = [du/dx, dv/dy, dw/dz, du/dy, dv/dx] //@todo not fully checked
552 answer(0, 0) = F [ 0 ] * C(0, 0) * F [ 0 ] + F [ 0 ] * C(0, 3) * F [ 3 ] + F [ 3 ] * C(3, 0) * F [ 0 ] + F [ 3 ] * C(3, 3) * F [ 3 ] + S [ 0 ];
553 answer(0, 1) = F [ 0 ] * C(0, 3) * F [ 4 ] + F [ 0 ] * C(0, 1) * F [ 1 ] + F [ 3 ] * C(3, 3) * F [ 4 ] + F [ 3 ] * C(3, 1) * F [ 1 ] + 0.0;
554 answer(0, 2) = F [ 0 ] * C(0, 2) * F [ 2 ] + F [ 3 ] * C(3, 2) * F [ 2 ] + 0.0;
555 answer(0, 3) = F [ 0 ] * C(0, 3) * F [ 0 ] + F [ 0 ] * C(0, 1) * F [ 3 ] + F [ 3 ] * C(3, 3) * F [ 0 ] + F [ 3 ] * C(3, 1) * F [ 3 ] + S [ 3 ];
556 answer(0, 4) = F [ 0 ] * C(0, 0) * F [ 4 ] + F [ 0 ] * C(0, 3) * F [ 1 ] + F [ 3 ] * C(3, 0) * F [ 4 ] + F [ 3 ] * C(3, 3) * F [ 1 ] + 0.0;
557 answer(1, 0) = F [ 4 ] * C(3, 0) * F [ 0 ] + F [ 4 ] * C(3, 3) * F [ 3 ] + F [ 1 ] * C(1, 0) * F [ 0 ] + F [ 1 ] * C(1, 3) * F [ 3 ] + 0.0;
558 answer(1, 1) = F [ 4 ] * C(3, 3) * F [ 4 ] + F [ 4 ] * C(3, 1) * F [ 1 ] + F [ 1 ] * C(1, 3) * F [ 4 ] + F [ 1 ] * C(1, 1) * F [ 1 ] + S [ 1 ];
559 answer(1, 2) = F [ 4 ] * C(3, 2) * F [ 2 ] + F [ 1 ] * C(1, 2) * F [ 2 ] + 0.0;
560 answer(1, 3) = F [ 4 ] * C(3, 3) * F [ 0 ] + F [ 4 ] * C(3, 1) * F [ 3 ] + F [ 1 ] * C(1, 3) * F [ 0 ] + F [ 1 ] * C(1, 1) * F [ 3 ] + 0.0;
561 answer(1, 4) = F [ 4 ] * C(3, 0) * F [ 4 ] + F [ 4 ] * C(3, 3) * F [ 1 ] + F [ 1 ] * C(1, 0) * F [ 4 ] + F [ 1 ] * C(1, 3) * F [ 1 ] + S [ 3 ];
562 answer(2, 0) = F [ 2 ] * C(2, 0) * F [ 0 ] + F [ 2 ] * C(2, 3) * F [ 3 ] + 0.0;
563 answer(2, 1) = F [ 2 ] * C(2, 3) * F [ 4 ] + F [ 2 ] * C(2, 1) * F [ 1 ] + 0.0;
564 answer(2, 2) = F [ 2 ] * C(2, 2) * F [ 2 ] + S [ 2 ];
565 answer(2, 3) = F [ 2 ] * C(2, 3) * F [ 0 ] + F [ 2 ] * C(2, 1) * F [ 3 ] + 0.0;
566 answer(2, 4) = F [ 2 ] * C(2, 0) * F [ 4 ] + F [ 2 ] * C(2, 3) * F [ 1 ] + 0.0;
567 answer(3, 0) = F [ 0 ] * C(3, 0) * F [ 0 ] + F [ 0 ] * C(3, 3) * F [ 3 ] + F [ 3 ] * C(1, 0) * F [ 0 ] + F [ 3 ] * C(1, 3) * F [ 3 ] + S [ 3 ];
568 answer(3, 1) = F [ 0 ] * C(3, 3) * F [ 4 ] + F [ 0 ] * C(3, 1) * F [ 1 ] + F [ 3 ] * C(1, 3) * F [ 4 ] + F [ 3 ] * C(1, 1) * F [ 1 ] + 0.0;
569 answer(3, 2) = F [ 0 ] * C(3, 2) * F [ 2 ] + F [ 3 ] * C(1, 2) * F [ 2 ] + 0.0;
570 answer(3, 3) = F [ 0 ] * C(3, 3) * F [ 0 ] + F [ 0 ] * C(3, 1) * F [ 3 ] + F [ 3 ] * C(1, 3) * F [ 0 ] + F [ 3 ] * C(1, 1) * F [ 3 ] + S [ 1 ];
571 answer(3, 4) = F [ 0 ] * C(3, 0) * F [ 4 ] + F [ 0 ] * C(3, 3) * F [ 1 ] + F [ 3 ] * C(1, 0) * F [ 4 ] + F [ 3 ] * C(1, 3) * F [ 1 ] + 0.0;
572 answer(4, 0) = F [ 4 ] * C(0, 0) * F [ 0 ] + F [ 4 ] * C(0, 3) * F [ 3 ] + F [ 1 ] * C(3, 0) * F [ 0 ] + F [ 1 ] * C(3, 3) * F [ 3 ] + 0.0;
573 answer(4, 1) = F [ 4 ] * C(0, 3) * F [ 4 ] + F [ 4 ] * C(0, 1) * F [ 1 ] + F [ 1 ] * C(3, 3) * F [ 4 ] + F [ 1 ] * C(3, 1) * F [ 1 ] + S [ 3 ];
574 answer(4, 2) = F [ 4 ] * C(0, 2) * F [ 2 ] + F [ 1 ] * C(3, 2) * F [ 2 ] + 0.0;
575 answer(4, 3) = F [ 4 ] * C(0, 3) * F [ 0 ] + F [ 4 ] * C(0, 1) * F [ 3 ] + F [ 1 ] * C(3, 3) * F [ 0 ] + F [ 1 ] * C(3, 1) * F [ 3 ] + 0.0;
576 answer(4, 4) = F [ 4 ] * C(0, 0) * F [ 4 ] + F [ 4 ] * C(0, 3) * F [ 1 ] + F [ 1 ] * C(3, 0) * F [ 4 ] + F [ 1 ] * C(3, 3) * F [ 1 ] + S [ 0 ];
577 return answer;
578}
579
582{
583 // Save terms associated with H = [du/dx dv/dy du/dy dv/dx]
585 answer(0, 0) = F [ 0 ] * C(0, 0) * F [ 0 ] + F [ 0 ] * C(0, 2) * F [ 2 ] + F [ 2 ] * C(2, 0) * F [ 0 ] + F [ 2 ] * C(2, 2) * F [ 2 ] + S [ 0 ];
586 answer(0, 1) = F [ 0 ] * C(0, 2) * F [ 3 ] + F [ 0 ] * C(0, 1) * F [ 1 ] + F [ 2 ] * C(2, 2) * F [ 3 ] + F [ 2 ] * C(2, 1) * F [ 1 ] + 0.0;
587 answer(0, 2) = F [ 0 ] * C(0, 2) * F [ 0 ] + F [ 0 ] * C(0, 1) * F [ 2 ] + F [ 2 ] * C(2, 2) * F [ 0 ] + F [ 2 ] * C(2, 1) * F [ 2 ] + S [ 2 ];
588 answer(0, 3) = F [ 0 ] * C(0, 0) * F [ 3 ] + F [ 0 ] * C(0, 2) * F [ 1 ] + F [ 2 ] * C(2, 0) * F [ 3 ] + F [ 2 ] * C(2, 2) * F [ 1 ] + 0.0;
589 answer(1, 0) = F [ 3 ] * C(2, 0) * F [ 0 ] + F [ 3 ] * C(2, 2) * F [ 2 ] + F [ 1 ] * C(1, 0) * F [ 0 ] + F [ 1 ] * C(1, 2) * F [ 2 ] + 0.0;
590 answer(1, 1) = F [ 3 ] * C(2, 2) * F [ 3 ] + F [ 3 ] * C(2, 1) * F [ 1 ] + F [ 1 ] * C(1, 2) * F [ 3 ] + F [ 1 ] * C(1, 1) * F [ 1 ] + S [ 1 ];
591 answer(1, 2) = F [ 3 ] * C(2, 2) * F [ 0 ] + F [ 3 ] * C(2, 1) * F [ 2 ] + F [ 1 ] * C(1, 2) * F [ 0 ] + F [ 1 ] * C(1, 1) * F [ 2 ] + 0.0;
592 answer(1, 3) = F [ 3 ] * C(2, 0) * F [ 3 ] + F [ 3 ] * C(2, 2) * F [ 1 ] + F [ 1 ] * C(1, 0) * F [ 3 ] + F [ 1 ] * C(1, 2) * F [ 1 ] + S [ 2 ];
593 answer(2, 0) = F [ 0 ] * C(2, 0) * F [ 0 ] + F [ 0 ] * C(2, 2) * F [ 2 ] + F [ 2 ] * C(1, 0) * F [ 0 ] + F [ 2 ] * C(1, 2) * F [ 2 ] + S [ 2 ];
594 answer(2, 1) = F [ 0 ] * C(2, 2) * F [ 3 ] + F [ 0 ] * C(2, 1) * F [ 1 ] + F [ 2 ] * C(1, 2) * F [ 3 ] + F [ 2 ] * C(1, 1) * F [ 1 ] + 0.0;
595 answer(2, 2) = F [ 0 ] * C(2, 2) * F [ 0 ] + F [ 0 ] * C(2, 1) * F [ 2 ] + F [ 2 ] * C(1, 2) * F [ 0 ] + F [ 2 ] * C(1, 1) * F [ 2 ] + S [ 1 ];
596 answer(2, 3) = F [ 0 ] * C(2, 0) * F [ 3 ] + F [ 0 ] * C(2, 2) * F [ 1 ] + F [ 2 ] * C(1, 0) * F [ 3 ] + F [ 2 ] * C(1, 2) * F [ 1 ] + 0.0;
597 answer(3, 0) = F [ 3 ] * C(0, 0) * F [ 0 ] + F [ 3 ] * C(0, 2) * F [ 2 ] + F [ 1 ] * C(2, 0) * F [ 0 ] + F [ 1 ] * C(2, 2) * F [ 2 ] + 0.0;
598 answer(3, 1) = F [ 3 ] * C(0, 2) * F [ 3 ] + F [ 3 ] * C(0, 1) * F [ 1 ] + F [ 1 ] * C(2, 2) * F [ 3 ] + F [ 1 ] * C(2, 1) * F [ 1 ] + S [ 2 ];
599 answer(3, 2) = F [ 3 ] * C(0, 2) * F [ 0 ] + F [ 3 ] * C(0, 1) * F [ 2 ] + F [ 1 ] * C(2, 2) * F [ 0 ] + F [ 1 ] * C(2, 1) * F [ 2 ] + 0.0;
600 answer(3, 3) = F [ 3 ] * C(0, 0) * F [ 3 ] + F [ 3 ] * C(0, 2) * F [ 1 ] + F [ 1 ] * C(2, 0) * F [ 3 ] + F [ 1 ] * C(2, 2) * F [ 1 ] + S [ 0 ];
601 return answer;
602}
603
606{
607 //Save terms associated with H = [du/dx]
610 answer(0, 0) = F [ 0 ] * C(0, 0) * F [ 0 ] + S [ 0 ];
611 return answer;
612}
613
614
615void
617{
618 OOFEM_ERROR("not implemented ")
619}
620
621
622void
624 MatResponseMode rMode,
625 GaussPoint *gp, TimeStep *tStep) const
626//
627// Returns characteristic material stiffness matrix of the receiver
628//
629{
630 MaterialMode mMode = gp->giveMaterialMode();
631 switch ( mMode ) {
632 case _3dMat:
633 answer = this->give3dMaterialStiffnessMatrix(rMode, gp, tStep);
634 break;
635 case _PlaneStress:
636 answer = this->givePlaneStressStiffMtrx(rMode, gp, tStep);
637 break;
638 case _PlaneStrain:
639 answer = this->givePlaneStrainStiffMtrx(rMode, gp, tStep);
640 break;
641 case _1dMat:
642 answer = this->give1dStressStiffMtrx(rMode, gp, tStep);
643 break;
644 case _PlateLayer:
645 answer = this->givePlateLayerStiffMtrx(rMode, gp, tStep);
646 break;
647 case _2dBeamLayer:
648 answer = this->give2dBeamLayerStiffMtrx(rMode, gp, tStep);
649 break;
650 case _Fiber:
651 answer = this->giveFiberStiffMtrx(rMode, gp, tStep);
652 break;
653 case _Warping:
654 answer = eye< 2 >();
655 break;
656 default:
657 OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode) );
658 }
659}
660
661
662
663
664void
666 MatResponseMode rMode,
667 GaussPoint *gp, TimeStep *tStep)
668//
669// Returns characteristic material stiffness matrix of the receiver
670//
671{
672 MaterialMode mMode = gp->giveMaterialMode();
673 switch ( mMode ) {
674 case _3dMat:
675 answer = this->give3dMaterialStiffnessMatrix_dPdF(rMode, gp, tStep);
676 break;
677 case _PlaneStress:
678 answer = this->givePlaneStressStiffnessMatrix_dPdF(rMode, gp, tStep);
679 break;
680 case _PlaneStrain:
681 answer = this->givePlaneStrainStiffnessMatrix_dPdF(rMode, gp, tStep);
682 break;
683 case _1dMat:
684 answer = this->give1dStressStiffnessMatrix_dPdF(rMode, gp, tStep);
685 break;
686 default:
687 OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode) );
688 }
689}
690
691
692
695 GaussPoint *gp, TimeStep *tStep) const
696{
697 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
698 const auto &vF = status->giveTempFVector();
699 const auto &vS = status->giveTempStressVector();
700 auto dSdE = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
701 return convert_dSdE_2_dPdF_3D(dSdE, vS, vF);
702}
703
704
707 GaussPoint *gp, TimeStep *tStep) const
708{
709 auto m3d = this->give3dMaterialStiffnessMatrix_dPdF(mode, gp, tStep);
710 return m3d({ 0, 1, 2, 5, 8 }, { 0, 1, 2, 5, 8 });
711}
712
713
716 GaussPoint *gp, TimeStep *tStep) const
717{
718 auto m3d = this->give3dMaterialStiffnessMatrix_dPdF(mode, gp, tStep);
719 auto c3d = inv(m3d);
720 return inv( FloatMatrixF<4,4>(c3d({ 0, 1, 5, 8 }, { 0, 1, 5, 8 })));
721}
722
723
726 GaussPoint *gp, TimeStep *tStep) const
727{
728 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
729 auto c3d = inv(m3d);
730 return { 1. / c3d.at(1, 1) };
731}
732
733
734void
736 MatResponseMode mode,
737 GaussPoint *gp, TimeStep *tStep)
738{
740 OOFEM_ERROR("There is no default implementation");
741}
742
743
744void
746 MatResponseMode mode,
747 GaussPoint *gp, TimeStep *tStep)
748{
749 OOFEM_ERROR("There is no default implementation");
750}
751
752
753void
755 MatResponseMode mode,
756 GaussPoint *gp, TimeStep *tStep)
757{
758 OOFEM_ERROR("There is no default implementation");
759}
760
761
762void
764 MatResponseMode mode,
765 GaussPoint *gp, TimeStep *tStep)
766{
767 OOFEM_ERROR("There is no default implementation");
768}
769
770
771void
773 const FloatArray &reducedStrainVector,
774 TimeStep *tStep, ValueModeType mode) const
775{
776 /*
777 * This functions subtract from reducedStrainVector its stress independent part
778 * caused by temperature, shrinkage and possibly by other phenomena.
779 */
780 answer = reducedStrainVector;
781 auto epsilonTemperature = this->computeStressIndependentStrainVector(gp, tStep, mode);
782 if ( epsilonTemperature.giveSize() ) {
783 answer.subtract(epsilonTemperature);
784 }
785}
786
787
788int
790{
791 IntArray indx;
793 return indx.giveSize();
794}
795
796
797int
799{
800 IntArray indx;
802 return indx.giveSize();
803}
804
805
806void
808{
809 IntArray mask;
811 answer.zero();
812 for ( int i = 1; i <= mask.giveSize(); i++ ) {
813 answer.at(mask.at(i) ) = i;
814 }
815}
816
817
818int
820{
821 // The same as giveVoigtVectorMask but returns a mask corresponding to a symmetric
822 // second order tensor.
823 //
824 // Returns a mask of the vector indices corresponding to components in a symmetric
825 // second order tensor of some stress/strain/deformation measure that performs work.
826 // Thus, components corresponding to imposed zero stress (e.g. plane stress etc.) are
827 // not included. On the other hand, if zero strain components are imposed( e.g. plane
828 // strain etc.) this condition must be taken into account in geometrical relations.
829 // Therefore, these corresponding components are included in the reduced vector.
830 // Which components to include are given by the particular MaterialMode.
831
832 switch ( mmode ) {
833 case _3dMat:
834 case _3dMicroplane:
835 answer.enumerate(6);
836 return 6;
837
838 case _3dDegeneratedShell:
839 answer = {
840 1, 2, 3, 4, 5, 6
841 };
842 return 6;
843
844
845 case _PlaneStress:
846 answer = {
847 1, 2, 6
848 };
849 return 6;
850
851 case _PlaneStrain:
852 answer = {
853 1, 2, 3, 6
854 };
855 return 6;
856
857 case _1dMat:
858 answer = {
859 1
860 };
861 return 6;
862
863 case _Warping:
864 answer = {
865 4, 5
866 };
867 return 6;
868
869 case _PlateLayer:
870 answer = {
871 1, 2, 4, 5, 6
872 };
873 return 6;
874
875 case _2dBeamLayer:
876 answer = {
877 1, 5
878 };
879 return 6;
880
881 case _Fiber:
882 answer = {
883 1, 5, 6
884 };
885 return 6;
886
887 case _2dPlate:
888 answer = {
889 4, 5, 6, 7, 8
890 };
891 return 8;
892
893 case _2dBeam:
894 answer = {
895 1, 4, 7
896 };
897 return 8;
898
899 case _3dBeam:
900#if 1
901 answer.enumerate(6);
902 return 6;
903
904#else
905 answer = {
906 1, 5, 6, 7, 8, 9
907 };
908 return 12;
909
910#endif
911 case _3dShell:
912 answer.enumerate(8);
913 return 8;
914
915 case _3dShellRot:
916 answer.enumerate(9);
917 return 9;
918
919 case _PlaneStressRot:
920 answer = {
921 1, 2, 6, 7
922 };
923 return 7;
924
925 case _1dInterface:
926 answer = {
927 1
928 };
929 return 1;
930
931 case _2dInterface:
932 answer = {
933 1, 2
934 };
935 return 2;
936
937 case _3dInterface:
938 answer = {
939 1, 2, 3
940 };
941 return 3;
942
943 case _1dLattice:
944 case _2dLattice:
945 case _3dLattice:
946 answer = {
947 1, 2, 3, 4, 5, 6
948 };
949 return 6;
950
951 case _2dPlateSubSoil:
952 answer = {
953 3, 5, 4
954 };
955 return 6;
956
957 case _3dBeamSubSoil:
958#if 1
959 answer.enumerate(6);
960 return 6;
961
962#else
963 answer = {
964 1, 5, 6, 7, 8, 9
965 };
966 return 12;
967
968#endif
969
970 case _Unknown:
971 answer.clear();
972 return 0;
973
974 default:
975 return 0;
976 }
977}
978
979
980int
982{
983 // Returns a mask of the vector indices corresponding to components in a general
984 // (non-symmetric) second order tensor of some stress/strain/deformation measure that
985 // performs work. Thus, components corresponding to imposed zero stress (e.g. plane
986 // stress etc.) are not included. On the other hand, if zero strain components are
987 // imposed( e.g. plane strain etc.) this condition must be taken into account in
988 // geometrical relations. Therefore, these corresponding components are included in
989 // the reduced vector. Which components to include are given by the particular MaterialMode.
990 //
992
993 switch ( mmode ) {
994 case _3dMat:
995 answer.resize(9);
996 for ( int i = 1; i <= 9; i++ ) {
997 answer.at(i) = i;
998 }
999
1000 return 9;
1001
1002 case _PlaneStress:
1003 answer.resize(4);
1004 answer.at(1) = 1;
1005 answer.at(2) = 2;
1006 answer.at(3) = 6;
1007 answer.at(4) = 9;
1008 return 9;
1009
1010 case _PlaneStrain:
1011 answer.resize(5);
1012 answer.at(1) = 1;
1013 answer.at(2) = 2;
1014 answer.at(3) = 3;
1015 answer.at(4) = 6;
1016 answer.at(5) = 9;
1017 return 9;
1018
1019 case _1dMat:
1020 answer.resize(1);
1021 answer.at(1) = 1;
1022 return 9;
1023
1024 default:
1025 return 0;
1026 }
1027}
1028
1029
1032 GaussPoint *gp,
1033 TimeStep *tStep) const
1034{
1035 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1036 auto c3d = inv(m3d);
1037 return inv(FloatMatrixF<3,3>(c3d({ 0, 1, 5 }, { 0, 1, 5 })));
1038}
1039
1042 GaussPoint *gp,
1043 TimeStep *tStep) const
1044{
1045 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1046 return m3d({ 0, 1, 2, 5 }, { 0, 1, 2, 5 });
1047}
1048
1051 GaussPoint *gp,
1052 TimeStep *tStep) const
1053{
1054 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1055 auto c3d = inv(m3d);
1056 return {
1057 1. / c3d.at(1, 1)
1058 };
1059}
1060
1061
1064 GaussPoint *gp,
1065 TimeStep *tStep) const
1066{
1067 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1068 auto c3d = inv(m3d);
1069 return inv(FloatMatrixF<2,2>(c3d({ 0, 4 }, { 0, 4 })));
1070}
1071
1072
1075 GaussPoint *gp,
1076 TimeStep *tStep) const
1077{
1078 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1079 auto c3d = inv(m3d);
1080 return inv(FloatMatrixF<5,5>(c3d({ 0, 1, 3, 4, 5 }, { 0, 1, 3, 4, 5 })));
1081}
1082
1085 GaussPoint *gp,
1086 TimeStep *tStep) const
1087{
1088 auto m3d = this->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1089 auto c3d = inv(m3d);
1090 return inv(FloatMatrixF<3,3>(c3d({ 0, 4, 5 }, { 0, 4, 5 })));
1091}
1092
1093
1096{
1097 OOFEM_ERROR("No general implementation provided");
1098}
1099
1102{
1103 OOFEM_ERROR("No general implementation provided");
1104}
1105
1106void
1108//
1109// This function computes the principal values of strains or stresses.
1110// Strains/stresses are stored in vector form in array s.
1111// Engineering notation is used.
1112//
1113// Problem size (3D/2D) is recognized automatically according to the
1114// vector size.
1115// If size = 6 -> 3D problem, then array s contains:
1116// {Sxx,Syy,Szz,Syz,Szx,Sxy} if mode = principal_stress
1117// {Exx,Eyy,Ezz,GMyz,GMzx,GMxy} if mode = principal_strain
1118// if size = 3 -> 2D problem, then array s contains:
1119// {Sxx,Syy,Sxy} if mode = principal_stress
1120// {Exx,Eyy,GMxy} if mode = principal_strain
1121//
1122// if size = 4 -> 2D problem (with normal out-of-plane component), then array s contains:
1123// {Sxx,Syy,Szz,Sxy} if mode = principal_stress
1124// {Exx,Eyy,Ezz,GMxy} if mode = principal_strain
1125//
1126// Return Values:
1127//
1128// array answer -> principal strains or stresses
1129//
1130{
1131 int size = s.giveSize();
1132 if ( !( size == 1 || size == 3 || size == 4 || size == 6 ) ) {
1133 OOFEM_SERROR("Vector size mismatch");
1134 }
1135
1136 double swap;
1137 int nonzeroFlag = 0;
1138 bool solve = true;
1139 if ( size == 1 ) {
1140 answer.resize(1);
1141 answer.at(1) = s.at(1);
1142 return;
1143 } else if ( size == 3 || size == 4 ) {
1144 // 2D problem
1145 double ast, dst, D = 0.0;
1146 answer.resize(size - 1);
1147
1148 for ( int i = 1; i <= size; i++ ) {
1149 if ( fabs(s.at(i) ) > 1.e-20 ) {
1150 nonzeroFlag = 1;
1151 }
1152 }
1153
1154 if ( nonzeroFlag == 0 ) {
1155 answer.zero();
1156 return;
1157 }
1158
1159 ast = s.at(1) + s.at(2);
1160 dst = s.at(1) - s.at(2);
1161 if ( mode == principal_strain ) {
1162 D = dst * dst + s.at(size) * s.at(size);
1163 } else if ( mode == principal_stress ) {
1164 D = dst * dst + 4.0 * s.at(size) * s.at(size);
1165 } else {
1166 OOFEM_SERROR("not supported");
1167 }
1168
1169 if ( D < 0. ) {
1170 OOFEM_SERROR("Imaginary roots ");
1171 }
1172
1173 D = sqrt(D);
1174 answer.at(1) = 0.5 * ( ast - D );
1175 answer.at(2) = 0.5 * ( ast + D );
1176 if ( size == 4 ) {
1177 answer.at(3) = s.at(3);
1178 }
1179 } else {
1180 // 3D problem
1181 double I1 = 0.0, I2 = 0.0, I3 = 0.0, help, s1, s2, s3;
1182
1183 for ( int i = 1; i <= size; i++ ) {
1184 if ( fabs(s.at(i) ) > 1.e-20 ) {
1185 nonzeroFlag = 1;
1186 }
1187 }
1188
1189 answer.resize(3);
1190 answer.zero();
1191 if ( nonzeroFlag == 0 ) {
1192 return;
1193 }
1194
1195 if ( mode == principal_stress ) {
1196 I1 = s.at(1) + s.at(2) + s.at(3);
1197 I2 = s.at(1) * s.at(2) + s.at(2) * s.at(3) + s.at(3) * s.at(1) -
1198 ( s.at(4) * s.at(4) + s.at(5) * s.at(5) + s.at(6) * s.at(6) );
1199 I3 = s.at(1) * s.at(2) * s.at(3) + 2. * s.at(4) * s.at(5) * s.at(6) -
1200 ( s.at(1) * s.at(4) * s.at(4) + s.at(2) * s.at(5) * s.at(5) +
1201 s.at(3) * s.at(6) * s.at(6) );
1202 } else if ( mode == principal_deviatoricstress ) {
1203 help = ( s.at(1) + s.at(2) + s.at(3) ) / 3.0;
1204 I1 = 0.;
1205 I2 = -( 1. / 6. ) * ( ( s.at(1) - s.at(2) ) * ( s.at(1) - s.at(2) ) + ( s.at(2) - s.at(3) ) * ( s.at(2) - s.at(3) ) +
1206 ( s.at(3) - s.at(1) ) * ( s.at(3) - s.at(1) ) ) - s.at(4) * s.at(4) - s.at(5) * s.at(5) -
1207 s.at(6) * s.at(6);
1208 I3 = ( s.at(1) - help ) * ( s.at(2) - help ) * ( s.at(3) - help ) + 2. * s.at(4) * s.at(5) * s.at(6) -
1209 s.at(5) * s.at(5) * ( s.at(2) - help ) - s.at(4) * s.at(4) * ( s.at(1) - help ) -
1210 s.at(6) * s.at(6) * ( s.at(3) - help );
1211 } else if ( mode == principal_strain ) {
1212 I1 = s.at(1) + s.at(2) + s.at(3);
1213 I2 = s.at(1) * s.at(2) + s.at(2) * s.at(3) + s.at(3) * s.at(1) -
1214 0.25 * ( s.at(4) * s.at(4) + s.at(5) * s.at(5) + s.at(6) * s.at(6) );
1215 I3 = s.at(1) * s.at(2) * s.at(3) +
1216 0.25 * ( s.at(4) * s.at(5) * s.at(6) - s.at(1) * s.at(4) * s.at(4) -
1217 s.at(2) * s.at(5) * s.at(5) - s.at(3) * s.at(6) * s.at(6) );
1218 } else {
1219 OOFEM_SERROR("not supported");
1220 }
1221
1222 /*
1223 * Call cubic3r to ensure that all three real eigenvalues will be found, because we have symmetric tensor.
1224 * This allows to overcome various rounding errors when solving general cubic equation.
1225 */
1226 int n;
1227 if ( solve ) {
1228 cubic3r( ( double ) -1., I1, -I2, I3, & s1, & s2, & s3, & n );
1229 if ( n > 0 ) {
1230 answer.at(1) = s1;
1231 }
1232
1233 if ( n > 1 ) {
1234 answer.at(2) = s2;
1235 }
1236
1237 if ( n > 2 ) {
1238 answer.at(3) = s3;
1239 }
1240
1241#if 0
1242 //Check NaN
1243 if ( answer.at(1) != answer.at(1) ) {
1244 s.pY();
1245 printf("%.10e %.10e %.10e\n", I1, I2, I3);
1246 exit(0);
1247 }
1248#endif
1249 }
1250 }
1251
1252 //sort the results
1253 for ( int i = 1; i < answer.giveSize(); i++ ) {
1254 for ( int j = 1; j < answer.giveSize(); j++ ) {
1255 if ( answer.at(j + 1) > answer.at(j) ) {
1256 swap = answer.at(j + 1);
1257 answer.at(j + 1) = answer.at(j);
1258 answer.at(j) = swap;
1259 }
1260 }
1261 }
1262}
1263
1264
1267{
1268 double I1 = s(0, 0) + s(1, 1) + s(2, 2);
1269 double I2 = s(0, 0) * s(1, 1) + s(1, 1) * s(2, 2) + s(2, 2) * s(0, 0) -
1270 ( s(0, 1) * s(1, 0) + s(0, 2) * s(2, 0) + s(1, 2) * s(2, 1) );
1271 double I3 = s(0, 0) * s(1, 1) * s(2, 2) + s(0, 1) * s(0, 2) * s(1, 2) + s(1, 0) * s(2, 0) * s(2, 1) -
1272 ( s(0, 0) * s(1, 2) * s(2, 1) + s(1, 1) * s(0, 2) * s(2, 0) + s(2, 2) * s(0, 1) * s(1, 0) );
1273
1274 return computePrincipalValues(I1, I2, I3);
1275}
1276
1277
1279StructuralMaterial::computePrincipalValues(double I1, double I2, double I3)
1280{
1281 double CUBIC_ZERO = 1e-100;
1282 double q = ( I1 * I1 - 3.0 * I2 ) / 9.0;
1283 double r = ( -2.0 * I1 * I1 * I1 + 9.0 * I1 * I2 - 27.0 * I3 ) / 54.0;
1284 double a3 = I1 / 3.0;
1285
1286 //Hydrostatic case, in such a case q=r=0
1287 if ( ( fabs(q) < CUBIC_ZERO ) && ( fabs(r) < CUBIC_ZERO ) ) {
1288 return {
1289 a3, a3, a3
1290 };
1291 }
1292
1293 // three real roots (clamping to prevent rounding errors
1294 double help = clamp(r / sqrt(q * q * q), -1., 1.);
1295 double phi = acos(help) / 3.0;
1296 double p = 2.0 * sqrt(q);
1297
1298 FloatArrayF< 3 >v = {
1299 a3 - p * cos(phi - 2. * M_PI / 3.),
1300 a3 - p * cos(phi),
1301 a3 - p * cos(phi + 2. * M_PI / 3.),
1302 };
1303 if ( v [ 0 ] > v [ 1 ] ) {
1304 std::swap(v [ 0 ], v [ 1 ]);
1305 }
1306 if ( v [ 1 ] > v [ 2 ] ) {
1307 std::swap(v [ 1 ], v [ 2 ]);
1308 }
1309 if ( v [ 0 ] > v [ 1 ] ) {
1310 std::swap(v [ 0 ], v [ 1 ]);
1311 }
1312 return v;
1313}
1314
1315
1316std::pair< FloatArrayF< 3 >, FloatMatrixF< 3, 3 > >
1318{
1319 //auto [eigVal, eigVec] = eig(s, 10);
1320 auto tmp = eig(s, 10);
1321 // Sort by largest eigenvalue
1322 for ( int ii = 0; ii < 2; ii++ ) {
1323 for ( int jj = 0; jj < 2; jj++ ) {
1324 if ( tmp.first [ jj + 1 ] > tmp.first [ jj ] ) {
1325 std::swap(tmp.first [ jj ], tmp.first [ jj + 1 ]);
1326 for ( int kk = 0; kk < 3; kk++ ) {
1327 std::swap(tmp.second(kk, jj), tmp.second(kk, jj + 1) );
1328 }
1329 }
1330 }
1331 }
1332 return tmp;
1333}
1334
1335
1336void
1338//
1339// This function computes the principal values & directions corresponding to principal values
1340// of strains or streses.
1341// strains/streses are stored in vector form in array s.
1342// Engineering notation is used.
1343//
1344// Problem size (3D/2D) is recognized automatically according to
1345// vector size.
1346// If size = 6 -> 3D problem, then array s contains:
1347// {Sxx,Syy,Szz,Syz,Szx,Sxy} if mode = principal_stress
1348// {Exx,Eyy,Ezz,GMyz,GMzx,GMxy} if mode = principal_strain
1349// if size = 3 -> 2D problem, then array s contains:
1350// {Sxx,Syy,Sxy} if mode = principal_stress
1351// {Exx,Eyy,GMxy} if mode = principal_strain
1352//
1353// mode - principal strains
1354// - principal stress
1355//
1356// Input Values:
1357// mode
1358// s
1359//
1360// Return Values:
1361//
1362// matrix dir -> principal directions of strains or stresses
1363// array answer -> principal strains or stresses
1364//
1365{
1366 FloatMatrix ss;
1367 FloatArray sp;
1368 double swap;
1369 int nval, size = s.giveSize();
1370 int nonzeroFlag = 0;
1371
1372 // printf ("size is %d\n",size);
1373 if ( !( size == 1 || size == 3 || size == 4 || size == 6 ) ) {
1374 OOFEM_SERROR("Vector size mismatch");
1375 }
1376
1377 if ( size == 1 ) {
1378 answer.resize(1);
1379 answer.at(1) = s.at(1);
1380 dir.resize(1, 1);
1381 dir.at(1, 1) = 1.0;
1382 return;
1383 } else if ( size == 3 || size == 4 ) {
1384 // 2D problem
1385 ss.resize(2, 2);
1386 answer.resize(2);
1387 dir.resize(2, 2);
1388
1389 for ( int i = 1; i <= size; i++ ) {
1390 if ( fabs(s.at(i) ) > 1.e-20 ) {
1391 nonzeroFlag = 1;
1392 }
1393 }
1394
1395 if ( nonzeroFlag == 0 ) {
1396 answer.zero();
1397 dir.zero();
1398 ss.zero();
1399 return;
1400 }
1401
1402 ss.at(1, 1) = s.at(1);
1403 ss.at(2, 2) = s.at(2);
1404
1405 if ( mode == principal_strain ) {
1406 ss.at(1, 2) = ss.at(2, 1) = 0.5 * s.at(size);
1407 } else if ( mode == principal_stress ) {
1408 ss.at(1, 2) = ss.at(2, 1) = s.at(size);
1409 } else {
1410 OOFEM_SERROR("not supported");
1411 }
1412 } else {
1413 // 3D problem
1414 double help;
1415 ss.resize(3, 3);
1416 answer.resize(3);
1417 dir.resize(3, 3);
1418
1419 for ( int i = 1; i <= size; i++ ) {
1420 if ( fabs(s.at(i) ) > 1.e-20 ) {
1421 nonzeroFlag = 1;
1422 }
1423 }
1424
1425 if ( nonzeroFlag == 0 ) {
1426 answer.zero();
1427 dir.zero();
1428 ss.zero();
1429 return;
1430 }
1431
1432 if ( mode == principal_stress ) {
1433 ss.at(1, 1) = s.at(1);
1434 ss.at(2, 2) = s.at(2);
1435 ss.at(3, 3) = s.at(3);
1436 ss.at(1, 2) = ss.at(2, 1) = s.at(6);
1437 ss.at(1, 3) = ss.at(3, 1) = s.at(5);
1438 ss.at(2, 3) = ss.at(3, 2) = s.at(4);
1439 } else if ( mode == principal_deviatoricstress ) {
1440 help = ( s.at(1) + s.at(2) + s.at(3) ) / 3.0;
1441 ss.at(1, 1) = s.at(1) - help;
1442 ss.at(2, 2) = s.at(2) - help;
1443 ss.at(3, 3) = s.at(3) - help;
1444 ss.at(1, 2) = ss.at(2, 1) = s.at(6);
1445 ss.at(1, 3) = ss.at(3, 1) = s.at(5);
1446 ss.at(2, 3) = ss.at(3, 2) = s.at(4);
1447 } else if ( mode == principal_strain ) {
1448 ss.at(1, 1) = s.at(1);
1449 ss.at(2, 2) = s.at(2);
1450 ss.at(3, 3) = s.at(3);
1451 ss.at(1, 2) = ss.at(2, 1) = 0.5 * s.at(6);
1452 ss.at(1, 3) = ss.at(3, 1) = 0.5 * s.at(5);
1453 ss.at(2, 3) = ss.at(3, 2) = 0.5 * s.at(4);
1454 } else {
1455 OOFEM_SERROR("not supported");
1456 }
1457 }
1458
1459#if 0
1460 ss.Jacobi(& answer, & dir, & i);
1461#else
1462 ss.jaco_(answer, dir, 10);
1463#endif
1464 // sort results
1465 nval = 2;
1466 if ( size == 6 ) {
1467 nval = 3;
1468 }
1469
1470 for ( int ii = 1; ii < nval; ii++ ) {
1471 for ( int jj = 1; jj < nval; jj++ ) {
1472 if ( answer.at(jj + 1) > answer.at(jj) ) {
1473 // swap eigen values and eigen vectors
1474 swap = answer.at(jj + 1);
1475 answer.at(jj + 1) = answer.at(jj);
1476 answer.at(jj) = swap;
1477 for ( int kk = 1; kk <= nval; kk++ ) {
1478 swap = dir.at(kk, jj + 1);
1479 dir.at(kk, jj + 1) = dir.at(kk, jj);
1480 dir.at(kk, jj) = swap;
1481 }
1482 }
1483 }
1484 }
1485}
1486
1487
1488std::pair< FloatArrayF< 6 >, double >
1490{
1491 double vol = s [ 0 ] + s [ 1 ] + s [ 2 ];
1492 double mean = vol / 3.0;
1493 auto dev = s;
1494 dev.at(1) -= mean;
1495 dev.at(2) -= mean;
1496 dev.at(3) -= mean;
1497 return {
1498 dev, mean
1499 };
1500}
1501
1502
1505{
1506 double vol = s [ 0 ] + s [ 1 ] + s [ 2 ];
1507 double mean = vol / 3.0;
1508 FloatArrayF< 6 >dev = s;
1509 dev.at(1) -= mean;
1510 dev.at(2) -= mean;
1511 dev.at(3) -= mean;
1512 return dev;
1513}
1514
1517{
1518 auto s = dev;
1519 s [ 0 ] += mean;
1520 s [ 1 ] += mean;
1521 s [ 2 ] += mean;
1522 return s;
1523}
1524
1527{
1528 return applyDeviatoricElasticCompliance(stress, EModulus / 2. / ( 1. + nu ) );
1529}
1530
1533{
1534 return {
1535 1. / ( 2. * GModulus ) * stress [ 0 ],
1536 1. / ( 2. * GModulus ) * stress [ 1 ],
1537 1. / ( 2. * GModulus ) * stress [ 2 ],
1538 1. / GModulus * stress [ 3 ],
1539 1. / GModulus * stress [ 4 ],
1540 1. / GModulus * stress [ 5 ],
1541 };
1542}
1543
1544
1547{
1548 return applyDeviatoricElasticStiffness(strain, EModulus / ( 2. * ( 1. + nu ) ) );
1549}
1550
1553{
1554 return {
1555 2. * GModulus * strain [ 0 ],
1556 2. * GModulus * strain [ 1 ],
1557 2. * GModulus * strain [ 2 ],
1558 GModulus *strain [ 3 ],
1559 GModulus *strain [ 4 ],
1560 GModulus *strain [ 5 ],
1561 };
1562}
1563
1565StructuralMaterial::applyElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
1566{
1567 double factor = EModulus / ( ( 1. + nu ) * ( 1. - 2. * nu ) );
1568
1569 return {
1570 factor *( ( 1. - nu ) * strain [ 0 ] + nu * strain [ 1 ] + nu * strain [ 2 ] ),
1571 factor *( nu * strain [ 0 ] + ( 1. - nu ) * strain [ 1 ] + nu * strain [ 2 ] ),
1572 factor *( nu * strain [ 0 ] + nu * strain [ 1 ] + ( 1. - nu ) * strain [ 2 ] ),
1573 factor *( ( ( 1. - 2. * nu ) / 2. ) * strain [ 3 ] ),
1574 factor *( ( ( 1. - 2. * nu ) / 2. ) * strain [ 4 ] ),
1575 factor *( ( ( 1. - 2. * nu ) / 2. ) * strain [ 5 ] ),
1576 };
1577}
1578
1580StructuralMaterial::applyElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
1581{
1582 return {
1583 ( stress [ 0 ] - nu * stress [ 1 ] - nu * stress [ 2 ] ) / EModulus,
1584 ( -nu * stress [ 0 ] + stress [ 1 ] - nu * stress [ 2 ] ) / EModulus,
1585 ( -nu * stress [ 0 ] - nu * stress [ 1 ] + stress [ 2 ] ) / EModulus,
1586 ( 2. * ( 1. + nu ) * stress [ 3 ] ) / EModulus,
1587 ( 2. * ( 1. + nu ) * stress [ 4 ] ) / EModulus,
1588 ( 2. * ( 1. + nu ) * stress [ 5 ] ) / EModulus,
1589 };
1590}
1591
1592double
1594{
1595 return sqrt(s [ 0 ] * s [ 0 ] + s [ 1 ] * s [ 1 ] + s [ 2 ] * s [ 2 ] +
1596 2. * s [ 3 ] * s [ 3 ] + 2. * s [ 4 ] * s [ 4 ] + 2. * s [ 5 ] * s [ 5 ]);
1597}
1598
1599double
1601{
1602 return s [ 0 ] + s [ 1 ] + s [ 2 ];
1603}
1604
1605double
1607{
1608 return .5 * ( s [ 0 ] * s [ 0 ] + s [ 1 ] * s [ 1 ] + s [ 2 ] * s [ 2 ] ) +
1609 s [ 3 ] * s [ 3 ] + s [ 4 ] * s [ 4 ] + s [ 5 ] * s [ 5 ];
1610}
1611
1612double
1614{
1615 return ( 1. / 3. ) * ( s [ 0 ] * s [ 0 ] * s [ 0 ] + 3. * s [ 0 ] * s [ 5 ] * s [ 5 ] +
1616 3. * s [ 0 ] * s [ 4 ] * s [ 4 ] + 6. * s [ 3 ] * s [ 5 ] * s [ 4 ] +
1617 3. * s [ 1 ] * s [ 5 ] * s [ 5 ] + 3 * s [ 2 ] * s [ 4 ] * s [ 4 ] +
1618 s [ 1 ] * s [ 1 ] * s [ 1 ] + 3. * s [ 1 ] * s [ 3 ] * s [ 3 ] +
1619 3. * s [ 2 ] * s [ 3 ] * s [ 3 ] + s [ 2 ] * s [ 2 ] * s [ 2 ] );
1620}
1621
1622
1623double
1625{
1626 // This function computes the first Haigh-Westergaard coordinate
1627 return computeFirstInvariant(s) / sqrt(3.);
1628}
1629
1630double
1632{
1633 // This function computes the second Haigh-Westergaard coordinate
1634 // from the deviatoric stress state
1635 return sqrt(2. * computeSecondStressInvariant(s) );
1636}
1637
1638double
1640{
1641 // This function computes the third Haigh-Westergaard coordinate
1642 // from the deviatoric stress state
1643 double c1 = 0.0;
1644 if ( computeSecondStressInvariant(s) == 0. ) {
1645 c1 = 0.0;
1646 } else {
1647 c1 = ( 3. * sqrt(3.) / 2. ) * computeThirdStressInvariant(s) / ( pow(computeSecondStressInvariant(s), ( 3. / 2. ) ) );
1648 }
1649
1650 if ( c1 > 1.0 ) {
1651 c1 = 1.0;
1652 }
1653
1654 if ( c1 < -1.0 ) {
1655 c1 = -1.0;
1656 }
1657
1658 return 1. / 3. * acos(c1);
1659}
1660
1661
1662double
1664{
1665 if ( stress.giveSize() == 3 ) {
1666 return computeVonMisesStress_PlaneStress(stress);
1667 } else if ( stress.giveSize() == 4 ) {
1668 // Plane strain
1669 double v1 = ( ( stress.at(1) - stress.at(2) ) * ( stress.at(1) - stress.at(2) ) );
1670 double v2 = ( ( stress.at(2) - stress.at(3) ) * ( stress.at(2) - stress.at(3) ) );
1671 double v3 = ( ( stress.at(3) - stress.at(1) ) * ( stress.at(3) - stress.at(1) ) );
1672
1673 double J2 = ( 1. / 6. ) * ( v1 + v2 + v3 ) + stress.at(4) * stress.at(4);
1674
1675 return sqrt(3 * J2);
1676 } else if ( stress.giveSize() == 6 ) {
1677 return computeVonMisesStress_3D(stress);
1678 } else {
1679 return 0.0;
1680 }
1681}
1682
1683
1684double
1686{
1687 return sqrt(stress.at(1) * stress.at(1) + stress.at(2) * stress.at(2)
1688 - stress.at(1) * stress.at(2) + 3 * stress.at(3) * stress.at(3) );
1689}
1690
1691
1692double
1694{
1695 double v1 = ( ( stress.at(1) - stress.at(2) ) * ( stress.at(1) - stress.at(2) ) );
1696 double v2 = ( ( stress.at(2) - stress.at(3) ) * ( stress.at(2) - stress.at(3) ) );
1697 double v3 = ( ( stress.at(3) - stress.at(1) ) * ( stress.at(3) - stress.at(1) ) );
1698
1699 double J2 = ( 1. / 6. ) * ( v1 + v2 + v3 ) + stress.at(4) * stress.at(4) +
1700 stress.at(5) * stress.at(5) + stress.at(6) * stress.at(6);
1701
1702 return sqrt(3 * J2);
1703}
1704
1705
1706
1709 bool trans)
1710//
1711// returns transformation matrix for 3d - strains to another system of axes,
1712// given by base.
1713// In base (FloatMatrix[3,3]) there are on each column stored vectors of
1714// coordinate system to which we do transformation.
1715//
1716// If transpose == 1 we transpose base matrix before transforming
1717//
1718{
1719 auto t = trans ? transpose(base) : base;
1720
1722 answer.at(1, 1) = t.at(1, 1) * t.at(1, 1);
1723 answer.at(1, 2) = t.at(2, 1) * t.at(2, 1);
1724 answer.at(1, 3) = t.at(3, 1) * t.at(3, 1);
1725 answer.at(1, 4) = t.at(2, 1) * t.at(3, 1);
1726 answer.at(1, 5) = t.at(1, 1) * t.at(3, 1);
1727 answer.at(1, 6) = t.at(1, 1) * t.at(2, 1);
1728
1729 answer.at(2, 1) = t.at(1, 2) * t.at(1, 2);
1730 answer.at(2, 2) = t.at(2, 2) * t.at(2, 2);
1731 answer.at(2, 3) = t.at(3, 2) * t.at(3, 2);
1732 answer.at(2, 4) = t.at(2, 2) * t.at(3, 2);
1733 answer.at(2, 5) = t.at(1, 2) * t.at(3, 2);
1734 answer.at(2, 6) = t.at(1, 2) * t.at(2, 2);
1735
1736 answer.at(3, 1) = t.at(1, 3) * t.at(1, 3);
1737 answer.at(3, 2) = t.at(2, 3) * t.at(2, 3);
1738 answer.at(3, 3) = t.at(3, 3) * t.at(3, 3);
1739 answer.at(3, 4) = t.at(2, 3) * t.at(3, 3);
1740 answer.at(3, 5) = t.at(1, 3) * t.at(3, 3);
1741 answer.at(3, 6) = t.at(1, 3) * t.at(2, 3);
1742
1743 answer.at(4, 1) = 2.0 * t.at(1, 2) * t.at(1, 3);
1744 answer.at(4, 2) = 2.0 * t.at(2, 2) * t.at(2, 3);
1745 answer.at(4, 3) = 2.0 * t.at(3, 2) * t.at(3, 3);
1746 answer.at(4, 4) = ( t.at(2, 2) * t.at(3, 3) + t.at(3, 2) * t.at(2, 3) );
1747 answer.at(4, 5) = ( t.at(1, 2) * t.at(3, 3) + t.at(3, 2) * t.at(1, 3) );
1748 answer.at(4, 6) = ( t.at(1, 2) * t.at(2, 3) + t.at(2, 2) * t.at(1, 3) );
1749
1750 answer.at(5, 1) = 2.0 * t.at(1, 1) * t.at(1, 3);
1751 answer.at(5, 2) = 2.0 * t.at(2, 1) * t.at(2, 3);
1752 answer.at(5, 3) = 2.0 * t.at(3, 1) * t.at(3, 3);
1753 answer.at(5, 4) = ( t.at(2, 1) * t.at(3, 3) + t.at(3, 1) * t.at(2, 3) );
1754 answer.at(5, 5) = ( t.at(1, 1) * t.at(3, 3) + t.at(3, 1) * t.at(1, 3) );
1755 answer.at(5, 6) = ( t.at(1, 1) * t.at(2, 3) + t.at(2, 1) * t.at(1, 3) );
1756
1757 answer.at(6, 1) = 2.0 * t.at(1, 1) * t.at(1, 2);
1758 answer.at(6, 2) = 2.0 * t.at(2, 1) * t.at(2, 2);
1759 answer.at(6, 3) = 2.0 * t.at(3, 1) * t.at(3, 2);
1760 answer.at(6, 4) = ( t.at(2, 1) * t.at(3, 2) + t.at(3, 1) * t.at(2, 2) );
1761 answer.at(6, 5) = ( t.at(1, 1) * t.at(3, 2) + t.at(3, 1) * t.at(1, 2) );
1762 answer.at(6, 6) = ( t.at(1, 1) * t.at(2, 2) + t.at(2, 1) * t.at(1, 2) );
1763
1764 return answer;
1765}
1766
1767
1770 bool trans)
1771//
1772// returns transformation matrix for 2d - strains to another system of axes,
1773// given by base.
1774// In base (FloatMatrix[2,2]) there are on each column stored vectors of
1775// coordinate system to which we do transformation.
1776//
1777// If transpose == 1 we transpose base matrix before transforming
1778//
1779{
1780 auto t = trans ? transpose(base) : base;
1782 answer.at(1, 1) = t.at(1, 1) * t.at(1, 1);
1783 answer.at(1, 2) = t.at(2, 1) * t.at(2, 1);
1784 answer.at(1, 3) = t.at(1, 1) * t.at(2, 1);
1785
1786 answer.at(2, 1) = t.at(1, 2) * t.at(1, 2);
1787 answer.at(2, 2) = t.at(2, 2) * t.at(2, 2);
1788 answer.at(2, 3) = t.at(1, 2) * t.at(2, 2);
1789
1790 answer.at(3, 1) = 2.0 * t.at(1, 1) * t.at(1, 2);
1791 answer.at(3, 2) = 2.0 * t.at(2, 1) * t.at(2, 2);
1792 answer.at(3, 3) = ( t.at(1, 1) * t.at(2, 2) + t.at(2, 1) * t.at(1, 2) );
1793 return answer;
1794}
1795
1796
1799 bool trans)
1800//
1801// returns transformation matrix for 3d - stress to another system of axes,
1802// given by base.
1803// In base (FloatMatrix[3,3]) there are on each column stored vectors of
1804// coordinate system to which we do transformation.
1805//
1806// If transpose == 1 we transpose base matrix before transforming
1807//
1808{
1809 auto t = trans ? transpose(base) : base;
1810
1812 answer.at(1, 1) = t.at(1, 1) * t.at(1, 1);
1813 answer.at(1, 2) = t.at(2, 1) * t.at(2, 1);
1814 answer.at(1, 3) = t.at(3, 1) * t.at(3, 1);
1815 answer.at(1, 4) = 2.0 * t.at(2, 1) * t.at(3, 1);
1816 answer.at(1, 5) = 2.0 * t.at(1, 1) * t.at(3, 1);
1817 answer.at(1, 6) = 2.0 * t.at(1, 1) * t.at(2, 1);
1818
1819 answer.at(2, 1) = t.at(1, 2) * t.at(1, 2);
1820 answer.at(2, 2) = t.at(2, 2) * t.at(2, 2);
1821 answer.at(2, 3) = t.at(3, 2) * t.at(3, 2);
1822 answer.at(2, 4) = 2.0 * t.at(2, 2) * t.at(3, 2);
1823 answer.at(2, 5) = 2.0 * t.at(1, 2) * t.at(3, 2);
1824 answer.at(2, 6) = 2.0 * t.at(1, 2) * t.at(2, 2);
1825
1826 answer.at(3, 1) = t.at(1, 3) * t.at(1, 3);
1827 answer.at(3, 2) = t.at(2, 3) * t.at(2, 3);
1828 answer.at(3, 3) = t.at(3, 3) * t.at(3, 3);
1829 answer.at(3, 4) = 2.0 * t.at(2, 3) * t.at(3, 3);
1830 answer.at(3, 5) = 2.0 * t.at(1, 3) * t.at(3, 3);
1831 answer.at(3, 6) = 2.0 * t.at(1, 3) * t.at(2, 3);
1832
1833 answer.at(4, 1) = t.at(1, 2) * t.at(1, 3);
1834 answer.at(4, 2) = t.at(2, 2) * t.at(2, 3);
1835 answer.at(4, 3) = t.at(3, 2) * t.at(3, 3);
1836 answer.at(4, 4) = ( t.at(2, 2) * t.at(3, 3) + t.at(3, 2) * t.at(2, 3) );
1837 answer.at(4, 5) = ( t.at(1, 2) * t.at(3, 3) + t.at(3, 2) * t.at(1, 3) );
1838 answer.at(4, 6) = ( t.at(1, 2) * t.at(2, 3) + t.at(2, 2) * t.at(1, 3) );
1839
1840 answer.at(5, 1) = t.at(1, 1) * t.at(1, 3);
1841 answer.at(5, 2) = t.at(2, 1) * t.at(2, 3);
1842 answer.at(5, 3) = t.at(3, 1) * t.at(3, 3);
1843 answer.at(5, 4) = ( t.at(2, 1) * t.at(3, 3) + t.at(3, 1) * t.at(2, 3) );
1844 answer.at(5, 5) = ( t.at(1, 1) * t.at(3, 3) + t.at(3, 1) * t.at(1, 3) );
1845 answer.at(5, 6) = ( t.at(1, 1) * t.at(2, 3) + t.at(2, 1) * t.at(1, 3) );
1846
1847 answer.at(6, 1) = t.at(1, 1) * t.at(1, 2);
1848 answer.at(6, 2) = t.at(2, 1) * t.at(2, 2);
1849 answer.at(6, 3) = t.at(3, 1) * t.at(3, 2);
1850 answer.at(6, 4) = ( t.at(2, 1) * t.at(3, 2) + t.at(3, 1) * t.at(2, 2) );
1851 answer.at(6, 5) = ( t.at(1, 1) * t.at(3, 2) + t.at(3, 1) * t.at(1, 2) );
1852 answer.at(6, 6) = ( t.at(1, 1) * t.at(2, 2) + t.at(2, 1) * t.at(1, 2) );
1853
1854 return answer;
1855}
1856
1857
1860 bool trans)
1861//
1862// returns transformation matrix for 2d - stress to another system of axes,
1863// given by base.
1864// In base (FloatMatrix[2,2]) there are on each column stored vectors of
1865// coordinate system to which we do transformation.
1866//
1867// If transpose == 1 we transpose base matrix before transforming
1868//
1869{
1870 auto t = trans ? transpose(base) : base;
1871
1873 answer.at(1, 1) = t.at(1, 1) * t.at(1, 1);
1874 answer.at(1, 2) = t.at(2, 1) * t.at(2, 1);
1875 answer.at(1, 3) = 2.0 * t.at(1, 1) * t.at(2, 1);
1876
1877 answer.at(2, 1) = t.at(1, 2) * t.at(1, 2);
1878 answer.at(2, 2) = t.at(2, 2) * t.at(2, 2);
1879 answer.at(2, 3) = 2.0 * t.at(1, 2) * t.at(2, 2);
1880
1881 answer.at(3, 1) = t.at(1, 1) * t.at(1, 2);
1882 answer.at(3, 2) = t.at(2, 1) * t.at(2, 2);
1883 answer.at(3, 3) = t.at(1, 1) * t.at(2, 2) + t.at(2, 1) * t.at(1, 2);
1884 return answer;
1885}
1886
1887
1890 const FloatArrayF< 6 > &strain, bool transpose)
1891//
1892// performs transformation of 3d-strain vector to another system of axes,
1893// given by base.
1894// In base (FloatMatrix[3,3]) there are on each column stored vectors of
1895// coordinate system to which we do transformation. These vectors must
1896// be expressed in the same coordinate system as strainVector
1897//
1898// If transpose == 1 we transpose base matrix before transforming
1899{
1901 return dot(tt, strain);
1902}
1903
1904
1907 const FloatArrayF< 6 > &stress, bool transpose)
1908//
1909//
1910// performs transformation of 3d-stress vector to another system of axes,
1911// given by base.
1912// In base (FloatMatrix[3,3]) there are on each column stored vectors of
1913// coordinate system to which we do transformation. These vectors must
1914// be expressed in the same coordinate system as strainVector
1915// If transpose == 1 we transpose base matrix before transforming
1916//
1917{
1919 return dot(tt, stress);
1920}
1921
1922
1923void
1925 const FloatMatrix &toPDir)
1926//
1927// this method sorts newly computed principal values (pVal) and
1928// corresponding principal directions (pDir) to be closed to
1929// some (often previous) principal directions (toPDir).
1930//
1931// remark : pDir and toPDir should have eigen vectors stored in columns
1932// and normalized.
1933//
1934{
1935 //
1936 // compute cosine matrix, where member i,j is cosine of angle
1937 // between toPDir i th eigen vector and j th pDir eigen vector
1938 //
1939 // sort pVal and pDir
1940 int maxJ = 0;
1941 for ( int i = 1; i <= 3 - 1; i++ ) {
1942 // find closest pDir vector to toPDir i-th vector
1943 double maxCosine = 0.0;
1944 for ( int j = i; j <= 3; j++ ) {
1945 double cosine = 0.;
1946 for ( int k = 1; k <= 3; k++ ) {
1947 cosine += toPDir.at(k, i) * pDir.at(k, j);
1948 }
1949
1950 cosine = fabs(cosine);
1951 if ( cosine > maxCosine ) {
1952 maxJ = j;
1953 maxCosine = cosine;
1954 }
1955 }
1956
1957 // swap entries
1958 if ( maxJ != i ) {
1959 // swap eigenVectors and values
1960 double swap = pVal.at(maxJ);
1961 pVal.at(maxJ) = pVal.at(i);
1962 pVal.at(i) = swap;
1963 for ( int k = 1; k <= 3; k++ ) {
1964 swap = pDir.at(k, maxJ);
1965 pDir.at(k, maxJ) = pDir.at(k, i);
1966 pDir.at(k, i) = swap;
1967 }
1968 }
1969 }
1970}
1971
1972
1973int
1975{
1976 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
1977 if ( type == IST_StressTensor ) {
1978 status->letStressVectorBe(value);
1979 return 1;
1980 } else if ( type == IST_StrainTensor ) {
1981 status->letStrainVectorBe(value);
1982 return 1;
1983 } else if ( type == IST_StressTensorTemp ) {
1984 status->letTempStressVectorBe(value);
1985 return 1;
1986 } else if ( type == IST_StrainTensorTemp ) {
1987 status->letTempStrainVectorBe(value);
1988 return 1;
1989 } else {
1990 return 0;
1991 }
1992}
1993
1994
1995int
1997{
1998 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
1999 if ( type == IST_StressTensor ) {
2001 return 1;
2002 } else if ( type == IST_StressTensor_Reduced ) {
2003 answer = status->giveStressVector();
2004 return 1;
2005 } else if ( type == IST_vonMisesStress ) {
2007 answer.resize(1);
2008 if ( status->giveStressVector().giveSize() == 6 ) {
2009 answer.at(1) = this->computeVonMisesStress_3D(status->giveStressVector() );
2010 } else {
2011 answer.at(1) = this->computeVonMisesStress(status->giveStressVector() );
2012 }
2013 return 1;
2014 } else if ( type == IST_StrainTensor ) {
2017 /* commented out by Milan - this evaluation of the out-of-plane strain would be correct for elastic material only
2018 * and for other materials can lead to misleading values
2019 * if ( gp->giveMaterialMode() == _PlaneStress) {
2020 * double Nxy = this->give(NYxy, gp);
2021 * double Nxz = this->give(NYxz, gp);
2022 * double Nyz = this->give(NYyz, gp);
2023 * double Nyx = Nxy * this->give(Ey, gp) / this->give(Ex, gp);
2024 * answer.at(3) = ( -( Nxz + Nxy * Nyz ) * answer.at(1) - ( Nyz + Nxz * Nyx ) * answer.at(2) ) / ( 1. - Nxy * Nyx );
2025 * }
2026 */
2027 return 1;
2028 } else if ( type == IST_StrainTensor_Reduced ) {
2030 answer = status->giveStrainVector();
2031 return 1;
2032 } else if ( type == IST_StressTensorTemp ) {
2035 return 1;
2036 } else if ( type == IST_StrainTensorTemp ) {
2039 return 1;
2040 } else if ( type == IST_PrincipalStressTensor || type == IST_PrincipalStressTempTensor ) {
2041 FloatArray s;
2042
2043 if ( type == IST_PrincipalStressTensor ) {
2046 } else {
2049 }
2050
2051 this->computePrincipalValues(answer, s, principal_stress);
2052 return 1;
2053 } else if ( type == IST_PrincipalStrainTensor || type == IST_PrincipalStrainTempTensor ) {
2054 FloatArray s;
2055
2056 if ( type == IST_PrincipalStrainTensor ) {
2059 } else {
2062 }
2063
2064 this->computePrincipalValues(answer, s, principal_strain);
2065 return 1;
2066 } else if ( type == IST_PrincStressVector1 || type == IST_PrincStressVector2 || type == IST_PrincStressVector3 ) {
2067 FloatArray arrAnswer;
2068 FloatMatrix dir;
2069 this->computePrincipalValDir(arrAnswer, dir, status->giveStressVector(), principal_stress);
2070 if ( type == IST_PrincStressVector1 ) {
2071 answer.beColumnOf(dir, 1);
2072 } else if ( type == IST_PrincStressVector2 ) {
2073 if ( dir.giveNumberOfColumns() >= 2 ) {
2074 answer.beColumnOf(dir, 2);
2075 } else {
2076 answer.beColumnOf(dir, 1);
2077 answer.zero();
2078 }
2079 } else {
2080 if ( dir.giveNumberOfColumns() >= 3 ) {
2081 answer.beColumnOf(dir, 3);
2082 } else {
2083 answer.beColumnOf(dir, 1);
2084 answer.zero();
2085 }
2086 }
2087 return 1;
2088 } else if ( type == IST_Temperature ) {
2089 /* add external source, if provided, such as staggered analysis */
2090 FieldManager *fm = domain->giveEngngModel()->giveContext()->giveFieldManager();
2091 FieldPtr tf;
2092 int err;
2093 if ( ( tf = fm->giveField(FT_Temperature) ) ) {
2094 // temperature field registered
2095 FloatArray gcoords, et2;
2096 static_cast< StructuralElement * >( gp->giveElement() )->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
2097 if ( ( err = tf->evaluateAt(answer, gcoords, VM_Total, tStep) ) ) {
2098 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", gp->giveElement()->giveNumber(), err);
2099 }
2100 } else {
2101 answer.resize(1);
2102 answer.zero();
2103 }
2104
2105 return 1;
2106 } else if ( type == IST_CylindricalStressTensor || type == IST_CylindricalStrainTensor ) {
2107 FloatArray gc, val = status->giveStressVector();
2108 FloatMatrix base(3, 3);
2110 double l = sqrt(gc.at(1) * gc.at(1) + gc.at(2) * gc.at(2) );
2111 if ( l > 1.e-4 ) {
2112 base.at(1, 1) = gc.at(1) / l;
2113 base.at(2, 1) = gc.at(2) / l;
2114 base.at(3, 1) = 0.0;
2115
2116 base.at(1, 2) = -1.0 * base.at(2, 1);
2117 base.at(2, 2) = base.at(1, 1);
2118 base.at(3, 2) = 0.0;
2119
2120 base.at(1, 3) = 0.0;
2121 base.at(2, 3) = 0.0;
2122 base.at(3, 3) = 1.0;
2123
2124 if ( type == IST_CylindricalStressTensor ) {
2125 answer = this->transformStressVectorTo(base, val, false);
2126 } else {
2127 answer = this->transformStrainVectorTo(base, val, false);
2128 }
2129 } else {
2130 answer = val;
2131 }
2132
2133 return 1;
2134 } else if ( type == IST_PlasticStrainTensor ) {
2136 answer.zero();
2137 return 1;
2138 } else if ( type == IST_MaxEquivalentStrainLevel ) {
2139 answer.resize(1);
2140 answer.at(1) = 0.;
2141 return 1;
2142 } else if ( type == IST_DeformationGradientTensor ) {
2143 answer = status->giveFVector();
2144 return 1;
2145 } else if ( type == IST_FirstPKStressTensor ) {
2146 answer = status->givePVector();
2147 return 1;
2148 } else if ( type == IST_EigenStrainTensor ) {
2149 FloatArray eigenstrain;
2150 StructuralElement *selem = dynamic_cast< StructuralElement * >( gp->giveElement() );
2151 selem->computeResultingIPEigenstrainAt(eigenstrain, tStep, gp, VM_Total);
2153 return 1;
2154 } else if ( type == IST_ShellForceTensor ) {
2155 answer.resize(6);
2156 answer.zero();
2157 return 1;
2158 } else {
2159 return Material::giveIPValue(answer, gp, type, tStep);
2160 }
2161}
2162
2165{
2166 FloatArray et, eigenstrain;
2167 if ( gp->giveIntegrationRule() == NULL ) {
2169 return FloatArray();
2170 }
2171 Element *elem = gp->giveElement();
2172 StructuralElement *selem = dynamic_cast< StructuralElement * >( gp->giveElement() );
2173
2174
2175 if ( tStep->giveIntrinsicTime() < this->castingTime ) {
2176 return FloatArray();
2177 }
2178
2179 //sum up all prescribed temperatures over an element
2180 //elem->computeResultingIPTemperatureAt(et, tStep, gp, mode);
2181 if ( selem ) {
2182 selem->computeResultingIPTemperatureAt(et, tStep, gp, mode);
2183 }
2184
2185 //sum up all prescribed eigenstrain over an element
2186 if ( selem ) {
2187 selem->computeResultingIPEigenstrainAt(eigenstrain, tStep, gp, mode);
2188 }
2189
2190 if ( eigenstrain.giveSize() != 0 && eigenstrain.giveSize() != giveSizeOfVoigtSymVector(gp->giveMaterialMode() ) ) {
2191 OOFEM_ERROR("Number of given eigenstrain components %d is different than required %d by element %d", (int)eigenstrain.giveSize(), giveSizeOfVoigtSymVector(gp->giveMaterialMode() ), elem->giveNumber() );
2192 }
2193
2194 /* add external source, if provided */
2195 FieldManager *fm = domain->giveEngngModel()->giveContext()->giveFieldManager();
2196 FieldPtr tf;
2197
2198 if ( ( tf = fm->giveField(FT_Temperature) ) ) {
2199 // temperature field registered
2200 FloatArray gcoords, et2;
2201 int err;
2202 elem->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
2203 if ( ( err = tf->evaluateAt(et2, gcoords, mode, tStep) ) ) {
2204 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err);
2205 }
2206
2207 if ( et2.isNotEmpty() ) {
2208 if ( et.isEmpty() ) {
2209 et = et2;
2210 } else {
2211 et.at(1) += et2.at(1);
2212 }
2213 }
2214 }
2215
2216 FloatArray answer;
2217 if ( et.giveSize() ) { //found temperature boundary conditions or prescribed field
2218 auto e0 = this->giveThermalDilatationVector(gp, tStep);
2219
2220 double scale = mode == VM_Total ? ( et.at(1) - this->referenceTemperature ) : et.at(1);
2221 FloatArray fullAnswer = e0 * scale;
2223 //answer = fullAnswer;
2224 }
2225
2226 //join temperature and eigenstrain vectors, compare vector sizes
2227 if ( answer.giveSize() ) {
2228 if ( eigenstrain.giveSize() ) {
2229 if ( answer.giveSize() != eigenstrain.giveSize() ) {
2230 OOFEM_ERROR("Vector of temperature strains has the size %d which is different with the size of eigenstrain vector %d, element %d", (int)answer.giveSize(), (int)eigenstrain.giveSize(), elem->giveNumber() );
2231 }
2232
2233 answer.add(eigenstrain);
2234 }
2235 } else {
2236 if ( eigenstrain.giveSize() ) {
2237 answer = eigenstrain;
2238 }
2239 }
2240
2241 //Add external eigenstrain if defined
2242 if ( ( tf = fm->giveField(FT_EigenStrain)) && (tf->hasElementInSets(selem->giveNumber(), this->giveDomain() )) ) {
2243 FloatArray gcoords, eigStrain;
2244 int err;
2245 elem->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
2246 if ( ( err = tf->evaluateAt(eigStrain, gcoords, mode, tStep) ) ) {
2247 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err);
2248 }
2249 if ( answer.giveSize() ) {
2250 if ( eigStrain.giveSize() ) {
2251 if ( answer.giveSize() != eigStrain.giveSize() ) {
2252 OOFEM_ERROR("Vector of eigen strain field has the size %d which is different with the size of eigStrain vector %d, element %d", (int)answer.giveSize(), (int)eigStrain.giveSize(), elem->giveNumber() );
2253 }
2254 answer.add(eigStrain);
2255 }
2256 } else {
2257 if ( eigStrain.giveSize() ) {
2258 answer = eigStrain;
2259 }
2260 }
2261 }
2262
2263 return answer;
2264}
2265
2266
2269{
2270 if ( gp->giveIntegrationRule() == NULL ) {
2272 return zeros< 6 >();
2273 }
2274
2275 if ( tStep->giveIntrinsicTime() < this->castingTime ) {
2276 return zeros< 6 >();
2277 }
2278
2279 //sum up all prescribed temperatures over an element
2280 //elem->computeResultingIPTemperatureAt(et, tStep, gp, mode);
2281 FloatArray et, eigenstrain;
2282 Element *elem = gp->giveElement();
2283 StructuralElement *selem = dynamic_cast< StructuralElement * >( gp->giveElement() );
2284 if ( selem ) {
2285 selem->computeResultingIPTemperatureAt(et, tStep, gp, mode);
2286 }
2287
2288 //sum up all prescribed eigenstrain over an element
2289 if ( selem ) {
2290 selem->computeResultingIPEigenstrainAt(eigenstrain, tStep, gp, mode);
2291 }
2292
2293 /* add external source, if provided */
2294 FieldManager *fm = domain->giveEngngModel()->giveContext()->giveFieldManager();
2295 FieldPtr tf = fm->giveField(FT_Temperature);
2296 if ( tf ) {
2297 // temperature field registered
2298 FloatArray gcoords, et2;
2299 elem->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
2300 int err;
2301 if ( ( err = tf->evaluateAt(et2, gcoords, mode, tStep) ) ) {
2302 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err);
2303 }
2304
2305 if ( et2.isNotEmpty() ) {
2306 if ( et.isEmpty() ) {
2307 et = et2;
2308 } else {
2309 et.at(1) += et2.at(1);
2310 }
2311 }
2312 }
2313
2314
2315 FloatArrayF< 6 >answer;
2316 if ( et.giveSize() ) { //found temperature boundary conditions or prescribed field
2317 auto e0 = this->giveThermalDilatationVector(gp, tStep);
2318 double scale = mode == VM_Total ? ( et.at(1) - this->referenceTemperature ) : et.at(1);
2319 answer = e0 * scale;
2320 }
2321 if ( eigenstrain.giveSize() ) {
2322 answer += FloatArrayF< 6 >(eigenstrain);
2323 }
2324
2325 //Add external eigenstrain if defined
2326 if ( ( tf = fm->giveField(FT_EigenStrain)) && (tf->hasElementInSets(selem->giveNumber(), this->giveDomain() )) ) {
2327 FloatArray gcoords, eigStrain;
2328 int err;
2329 elem->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
2330 if ( ( err = tf->evaluateAt(eigStrain, gcoords, mode, tStep) ) ) {
2331 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err);
2332 }
2333 if ( answer.giveSize() ) {
2334 answer += FloatArrayF< 6 >(eigStrain);
2335 }
2336 }
2337 return answer;
2338}
2339
2340
2341void
2342StructuralMaterial::giveFullSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
2343{
2344 if ( vec.giveSize() == 6 ) {
2345 // If we use default 3D implementation to treat e.g. plane strain.
2346 answer = vec;
2347 } else {
2348 IntArray indx;
2349 answer.resize(StructuralMaterial::giveVoigtSymVectorMask(indx, matMode) );
2350 answer.zero();
2351 answer.assemble(vec, indx);
2352 }
2353}
2354
2355
2356void
2357StructuralMaterial::giveFullVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
2358{
2359 if ( vec.giveSize() == 9 ) {
2360 // If we use default 3D implementation to treat e.g. plane strain.
2361 answer = vec;
2362 } else {
2363 IntArray indx;
2364 answer.resize(StructuralMaterial::giveVoigtVectorMask(indx, matMode) );
2365 answer.zero();
2366 answer.assemble(vec, indx);
2367 }
2368}
2369
2370
2371void
2372StructuralMaterial::giveFullVectorFormF(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
2373{
2374 if ( vec.giveSize() == 9 ) {
2375 // If we use default 3D implementation to treat e.g. plane strain.
2376 answer = vec;
2377 } else {
2378 IntArray indx;
2379 answer.resize(9);
2380 answer.at(1) = answer.at(2) = answer.at(3) = 1.0; // set diagonal terms
2381
2383 for ( int i = 1; i <= indx.giveSize(); i++ ) {
2384 answer.at(indx.at(i) ) = vec.at(i);
2385 }
2386 }
2387}
2388
2389
2390void
2391StructuralMaterial::giveReducedVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
2392{
2393 IntArray indx;
2395 answer.beSubArrayOf(vec, indx);
2396}
2397
2398
2399void
2401{
2402 IntArray indx;
2404
2405 if ( indx.giveSize() == vec.giveSize() ) {
2406 answer = vec;
2407 } else {
2408 answer.beSubArrayOf(vec, indx);
2409 }
2410}
2411
2412
2413void
2415{
2416 IntArray indx;
2417 int size = StructuralMaterial::giveVoigtSymVectorMask(indx, matMode);
2418 answer.resize(size, size);
2419 answer.zero();
2420 answer.assemble(red, indx, indx);
2421}
2422
2423
2424void
2425StructuralMaterial::giveReducedMatrixForm(FloatMatrix &answer, const FloatMatrix &full, MaterialMode matMode)
2426{
2427 IntArray indx;
2429 answer.beSubMatrixOf(full, indx, indx);
2430}
2431
2432
2433void
2435{
2436 IntArray indx;
2438 answer.beSubMatrixOf(full, indx, indx);
2439}
2440
2443{
2444 double alpha = this->give(tAlpha, gp);
2445 return {
2446 alpha,
2447 alpha,
2448 alpha,
2449 0.,
2450 0.,
2451 0.,
2452 };
2453}
2454
2455void
2457{
2459
2462
2463 double alpha = 0.0;
2465 if ( !propertyDictionary.includes(tAlpha) ) {
2466 // if (alpha > 0.0 && !propertyDictionary.includes(tAlpha)) {
2467 // put isotropic thermal expansion coeff into dictionary, if provided
2468 // and not previosly defined
2469 propertyDictionary.add(tAlpha, alpha);
2470 }
2471 int stiffmode = 0;
2473 this->SCStiffMode = ( MatResponseMode ) stiffmode;
2474
2478}
2479
2480
2481void
2490} // end namespace oofem
#define E(a, b)
void setField(int item, InputFieldType id)
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int giveNumber() const
Definition femcmpnn.h:104
FieldPtr giveField(FieldType key)
double & at(std::size_t i)
int giveSize() const
Returns the size of receiver.
double computeNorm() const
Definition floatarray.C:861
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
virtual void pY() const
Definition floatarray.C:802
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beColumnOf(const FloatMatrix &mat, int col)
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
bool isEmpty() const
Returns true if receiver is empty.
Definition floatarray.h:265
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void beSubArrayOf(const FloatArray &src, const IntArray &indx)
Definition floatarray.C:440
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition floatarray.h:263
double at(std::size_t i, std::size_t j) const
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
int giveNumberOfColumns() const
Returns number of columns of receiver.
bool jaco_(FloatArray &eval, FloatMatrix &v, int nf)
void zero()
Zeroes all coefficient of receiver.
bool beInverseOf(const FloatMatrix &src)
void assemble(const FloatMatrix &src, const IntArray &loc)
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
IntegrationRule * giveIntegrationRule()
Returns corresponding integration rule to receiver.
Definition gausspoint.h:185
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
void enumerate(int maxVal)
Definition intarray.C:85
void resize(int n)
Definition intarray.C:73
bool contains(int value) const
Definition intarray.h:292
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
Material(int n, Domain *d)
Definition material.C:46
void initializeFrom(InputRecord &ir) override
Definition material.C:93
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
void giveInputRecord(DynamicInputRecord &input) override
Definition material.C:113
Dictionary propertyDictionary
Definition material.h:107
virtual double give(int aProperty, GaussPoint *gp) const
Definition material.C:51
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Definition material.C:138
virtual void computeResultingIPEigenstrainAt(FloatArray &answer, TimeStep *tStep, GaussPoint *gp, ValueModeType mode)
virtual void computeResultingIPTemperatureAt(FloatArray &answer, TimeStep *tStep, GaussPoint *gp, ValueModeType mode)
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
const FloatArray & giveFVector() const
Returns the const pointer to receiver's deformation gradient vector.
void letStressVectorBe(const FloatArray &v)
Assigns stressVector to given vector v.
const FloatArray & giveTempFVector() const
Returns the const pointer to receiver's temporary deformation gradient vector.
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
void letStrainVectorBe(const FloatArray &v)
Assigns strain vector to given vector v.
const FloatArray & givePVector() const
Returns the const pointer to receiver's first Piola-Kirchhoff stress vector.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
const FloatArray & giveTempStrainVector() const
Returns the const pointer to receiver's temporary strain vector.
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
virtual void give1dStressStiffMtrx_dCde(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
virtual FloatMatrixF< 3, 3 > givePlaneStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
void giveInputRecord(DynamicInputRecord &input) override
static double computeThirdCoordinate(const FloatArrayF< 6 > &s)
virtual FloatArrayF< 3 > giveRealStressVector_2dPlateSubSoil(const FloatArrayF< 3 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation is not provided.
virtual void giveEshelbyStressVector_PlaneStrain(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedF, TimeStep *tStep)
virtual FloatArrayF< 1 > giveRealStressVector_1d(const FloatArrayF< 1 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
virtual FloatArrayF< 2 > giveRealStressVector_2dBeamLayer(const FloatArrayF< 2 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
static std::array< std::array< int, 3 >, 3 > svIndex
Symmetric Voigt index map.
static std::array< std::array< int, 3 >, 3 > vIindex
Voigt index map.
virtual FloatArrayF< 1 > giveFirstPKStressVector_1d(const FloatArrayF< 1 > &vF, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveFirstPKStressVector_StressControl.
static FloatArrayF< 6 > computeDeviatoricVolumetricSum(const FloatArrayF< 6 > &dev, double mean)
static int giveVI(int ind1, int ind2)
virtual FloatArrayF< 2 > giveRealStressVector_Warping(const FloatArrayF< 2 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
virtual FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrixF< 3, 3 > give2dPlateSubSoilStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static FloatMatrixF< 1, 1 > convert_dSdE_2_dPdF_1D(const FloatMatrixF< 1, 1 > &dSdE, const FloatArrayF< 1 > &S, const FloatArrayF< 1 > &F)
virtual FloatMatrixF< 1, 1 > give1dStressStiffnessMatrix_dPdF(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static FloatMatrixF< 3, 3 > givePlaneStressVectorTranformationMtrx(const FloatMatrixF< 2, 2 > &base, bool transpose=false)
virtual FloatArrayF< 5 > giveRealStressVector_PlateLayer(const FloatArrayF< 5 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
static FloatArrayF< 6 > applyElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
static void giveFullSymMatrixForm(FloatMatrix &answer, const FloatMatrix &red, MaterialMode matMode)
Converts the full unsymmetric Voigt matrix (4th order tensor) to reduced form.
static FloatArrayF< 6 > applyElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
virtual void give3dMaterialStiffnessMatrix_dCde(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
static FloatMatrixF< 6, 6 > giveStressVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
virtual void givePlaneStrainStiffMtrx_dCde(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
bool hasMaterialModeCapability(MaterialMode mode) const override
virtual FloatMatrixF< 5, 5 > givePlaneStrainStiffnessMatrix_dPdF(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
static void giveReducedSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the full unsymmetric Voigt vector (2nd order tensor) to reduced form.
static FloatArrayF< 6 > applyDeviatoricElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
void initializeFrom(InputRecord &ir) override
static double computeThirdStressInvariant(const FloatArrayF< 6 > &s)
virtual FloatMatrixF< 4, 4 > givePlaneStrainStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static FloatMatrixF< 4, 4 > convert_dSdE_2_dPdF_PlaneStress(const FloatMatrixF< 3, 3 > &dSdE, const FloatArrayF< 3 > &S, const FloatArrayF< 4 > &F)
StructuralMaterial(int n, Domain *d)
virtual void giveStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
double referenceTemperature
Reference temperature (temperature, when material has been built into structure).
static double computeFirstCoordinate(const FloatArrayF< 6 > &s)
virtual FloatArrayF< 4 > giveRealStressVector_PlaneStrain(const FloatArrayF< 4 > &strain, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_3d.
static FloatArrayF< 6 > applyDeviatoricElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
virtual FloatArrayF< 3 > giveRealStressVector_Fiber(const FloatArrayF< 3 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
static double computeStressNorm(const FloatArrayF< 6 > &stress)
static int giveSymVI(int ind1, int ind2)
static int giveVoigtVectorMask(IntArray &answer, MaterialMode mmode)
virtual FloatArrayF< 5 > giveFirstPKStressVector_PlaneStrain(const FloatArrayF< 5 > &vF, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveFirstPKStressVector_3d.
static double computeSecondStressInvariant(const FloatArrayF< 6 > &s)
virtual FloatArray giveFirstPKStressVector_StressControl(const FloatArray &reducedvF, const IntArray &FControl, GaussPoint *gp, TimeStep *tStep) const
Iteratively calls giveRealStressVector_3d to find the stress controlled equal to zero·
static FloatArrayF< 6 > computeDeviator(const FloatArrayF< 6 > &s)
static double computeVonMisesStress(const FloatArray &currentStress)
double SCRelTol
relative tolerance for stress control
static void sortPrincDirAndValCloseTo(FloatArray &pVal, FloatMatrix &pDir, const FloatMatrix &toPDir)
void giveCharacteristicMatrix(FloatMatrix &answer, MatResponseMode type, GaussPoint *gp, TimeStep *tStep) const override
Returns characteristic matrix of the receiver.
static int giveVoigtSymVectorMask(IntArray &answer, MaterialMode mmode)
static void giveFullVectorFormF(FloatArray &answer, const FloatArray &strainVector, MaterialMode matMode)
Converts the reduced deformation gradient Voigt vector (2nd order tensor).
virtual FloatArray giveRealStressVector_StressControl(const FloatArray &reducedE, const IntArray &strainControl, GaussPoint *gp, TimeStep *tStep) const
Iteratively calls giveRealStressVector_3d to find the stress controlled equal to zero·
static void giveReducedSymMatrixForm(FloatMatrix &answer, const FloatMatrix &full, MaterialMode matMode)
Converts the full unsymmetric Voigt matrix (4th order tensor) to reduced form.
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
int setIPValue(const FloatArray &value, GaussPoint *gp, InternalStateType type) override
virtual FloatMatrixF< 5, 5 > givePlateLayerStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static double computeVonMisesStress_3D(const FloatArrayF< 6 > &stress)
static FloatMatrixF< 5, 5 > convert_dSdE_2_dPdF_PlaneStrain(const FloatMatrixF< 4, 4 > &dSdE, const FloatArrayF< 4 > &S, const FloatArrayF< 5 > &F)
virtual FloatMatrixF< 6, 6 > give3dBeamSubSoilStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
MatResponseMode SCStiffMode
stifness mode used in stress control
static FloatMatrixF< 6, 6 > giveStrainVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
virtual FloatArrayF< 6 > giveThermalDilatationVector(GaussPoint *gp, TimeStep *tStep) const
static FloatMatrixF< 9, 9 > convert_dSdE_2_dPdF_3D(const FloatMatrixF< 6, 6 > &dSdE, const FloatArrayF< 6 > &S, const FloatArrayF< 9 > &F)
static void giveReducedVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the full symmetric Voigt vector (2nd order tensor) to reduced form.
static void giveFullVectorForm(FloatArray &answer, const FloatArray &strainVector, MaterialMode matMode)
Converts the reduced symmetric Voigt vector (2nd order tensor) to full form.
static void giveReducedMatrixForm(FloatMatrix &answer, const FloatMatrix &full, MaterialMode matMode)
Converts the full symmetric Voigt matrix (4th order tensor) to reduced form.
static FloatArrayF< 6 > transformStrainVectorTo(const FloatMatrixF< 3, 3 > &base, const FloatArrayF< 6 > &strain, bool transpose=false)
static double computeVonMisesStress_PlaneStress(const FloatArrayF< 3 > &stress)
int SCMaxiter
maximum iterations for stress-control
virtual FloatArrayF< 6 > giveRealStressVector_3d(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
static int giveSizeOfVoigtSymVector(MaterialMode mmode)
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
static FloatMatrixF< 3, 3 > give2DStrainVectorTranformationMtrx(const FloatMatrixF< 2, 2 > &base, bool transpose=false)
static double computeSecondCoordinate(const FloatArrayF< 6 > &s)
static FloatArrayF< 6 > transformStressVectorTo(const FloatMatrixF< 3, 3 > &base, const FloatArrayF< 6 > &stress, bool transpose=false)
static void giveInvertedVoigtVectorMask(IntArray &answer, MaterialMode mmode)
virtual FloatMatrixF< 4, 4 > givePlaneStressStiffnessMatrix_dPdF(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrixF< 1, 1 > give1dStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static std::pair< FloatArrayF< 6 >, double > computeDeviatoricVolumetricSplit(const FloatArrayF< 6 > &s)
virtual FloatArrayF< 4 > giveFirstPKStressVector_PlaneStress(const FloatArrayF< 4 > &vF, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveFirstPKStressVector_StressControl.
double SCAbsTol
absolute stress tolerance for stress control
virtual void giveStiffnessMatrix_dPdF(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
FloatArrayF< 6 > computeStressIndependentStrainVector_3d(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
static double computeFirstInvariant(const FloatArrayF< 6 > &s)
virtual FloatArrayF< 3 > giveRealStressVector_PlaneStress(const FloatArrayF< 3 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
void giveCharacteristicVector(FloatArray &answer, FloatArray &flux, MatResponseMode type, GaussPoint *gp, TimeStep *tStep) const override
Returns characteristic vector of the receiver.
static void giveFullSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the reduced unsymmetric Voigt vector (2nd order tensor) to full form.
virtual FloatMatrixF< 2, 2 > give2dBeamLayerStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArray computeStressIndependentStrainVector(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
virtual FloatMatrixF< 9, 9 > give3dMaterialStiffnessMatrix_dPdF(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArray giveRealStressVector_ShellStressControl(const FloatArray &reducedE, const IntArray &strainControl, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrixF< 3, 3 > giveFiberStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
static int giveSizeOfVoigtVector(MaterialMode mmode)
virtual void giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep) const
virtual FloatArrayF< 9 > giveFirstPKStressVector_3d(const FloatArrayF< 9 > &vF, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
virtual void givePlaneStressStiffMtrx_dCde(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
virtual FloatArrayF< 6 > giveRealStressVector_3dBeamSubSoil(const FloatArrayF< 6 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
double giveIntrinsicTime()
Returns intrinsic time, e.g. time in which constitutive model is evaluated.
Definition timestep.h:166
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_SERROR(...)
Definition error.h:81
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define tAlpha
Definition matconst.h:67
#define CUBIC_ZERO
Definition mathfem.C:40
#define M_PI
Definition mathfem.h:52
#define S(p)
Definition mdm.C:469
FloatArrayF< 6 > to_voigt_strain_33(const FloatMatrixF< 3, 3 > &t)
FloatMatrixF< M, N > transpose(const FloatMatrixF< N, M > &mat)
Constructs transposed matrix.
FloatMatrixF< N, P > Tdot(const FloatMatrixF< M, N > &a, const FloatMatrixF< M, P > &b)
Computes .
FloatMatrixF< 3, 3 > from_voigt_form_9(const FloatArrayF< 9 > &v)
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
std::pair< FloatArrayF< N >, FloatMatrixF< N, N > > eig(const FloatMatrixF< N, N > &mat, int nf=9)
void cubic3r(double a, double b, double c, double d, double *r1, double *r2, double *r3, int *num)
Definition mathfem.C:155
FloatMatrixF< 3, 3 > from_voigt_stress_6(const FloatArrayF< 6 > &v)
@ principal_strain
For computing principal strains from engineering strains.
@ principal_stress
For computing principal stresses.
@ principal_deviatoricstress
For computing principal stresses from deviatoric stress.
FloatArrayF< 9 > to_voigt_form_33(const FloatMatrixF< 3, 3 > &t)
FloatArrayF< N > solve(FloatMatrixF< N, N > mtrx, const FloatArrayF< N > &b, double zeropiv=1e-20)
double dot(const FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.
std::shared_ptr< Field > FieldPtr
Definition field.h:78
FloatArrayF< N > zeros()
For more readable code.
FloatMatrixF< N, N > eye()
Constructs an identity matrix.
double clamp(int a, int lower, int upper)
Returns the clamped value of a between upper and lower.
Definition mathfem.h:88
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define _IFT_StructuralMaterial_referencetemperature
#define _IFT_StructuralMaterial_talpha
#define _IFT_StructuralMaterial_StressControl_reltol
#define _IFT_StructuralMaterial_StressControl_stiffmode
#define _IFT_StructuralMaterial_StressControl_maxiter
#define _IFT_StructuralMaterial_StressControl_abstol

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011