1 /*
2     Copyright (C) 1998  Dennis Roddeman
3     email: dennis.roddeman@feat.nl
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software Foundation
17     59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA
18 */
19 
20 #include "tochnog.h"
21 
22 extern "C"
23   int umat_(double *stress, double *statev, double *ddsdde,
24     double *sse, double *spd, double *scd, double *rpl, double *ddsddt,
25     double *drplde, double *drpldt, double *stran, double *dstran,
26     double *time, double *dtime, double *temp, double *dtemp, double *predef,
27     double *dpred, char *cmname, long int *ndi,
28     long int *nshr, long int *ntens, long int *nstatv,
29     double *props, long int *nprops, double *coords, double *drot,
30     double *pnewdt, double *celent, double *dfgrd0, double *dfgrd1,
31     long int *noel, long int *npt, long int *layer, long int *kspt,
32     long int *kstep, long int *kinc, short cmname_len);
33 
34 #define MAX_ITER 1000
35 #define EPS_F 1.e-6
36 #define EPS_EPS_F 1.e-3
37 #define EPS_SIZE 1.e-3
38 #define EPS_DAMAGE 1.e-5
39 #define EPS_TMP 1.e-1
40 #define EPS_LAMBDA 1.e-3
41 #define EPS_VISCO 3.
42 
set_stress(long int element,long int gr,long int plasti_on_boundary,double coord_ip[],double old_unknowns[],double new_unknowns[],double old_grad_old_unknowns[],double new_grad_new_unknowns[],double rotated_old_sig[],double new_sig[],double rotated_old_msig[],double new_msig[],double inc_ept[],double new_ept[],double old_epe[],double inc_epe[],double old_epp[],double inc_epp[],double old_rho[],double new_rho[],double old_epi[],double new_epi[],double old_hisv[],double new_hisv[],double old_damage,double & new_damage,double old_kappa,double & new_kappa,double & new_f,double & new_substeps,double old_deften[],double new_deften[],double inc_rot[],double ddsdde[],double & viscosity,double & viscosity_heat_generation,double & softvar_nonl,double & softvar_l)43 void set_stress( long int element, long int gr,
44   long int plasti_on_boundary, double coord_ip[],
45   double old_unknowns[], double new_unknowns[],
46   double old_grad_old_unknowns[], double new_grad_new_unknowns[],
47   double rotated_old_sig[], double new_sig[],
48   double rotated_old_msig[], double new_msig[],
49   double inc_ept[], double new_ept[],
50   double old_epe[], double inc_epe[],
51   double old_epp[], double inc_epp[],
52   double old_rho[], double new_rho[],
53   double old_epi[], double new_epi[],
54   double old_hisv[], double new_hisv[],
55   double old_damage, double &new_damage,
56   double old_kappa, double &new_kappa,
57   double &new_f, double &new_substeps, double old_deften[], double new_deften[],
58   double inc_rot[], double ddsdde[],
59   double &viscosity, double &viscosity_heat_generation, double &softvar_nonl,
60   double &softvar_l )
61 
62   // Solid materials.
63 
64 {
65   long int i=0, j=0, ind_ddsdde=0, plasti_found=0,
66     plasti_iter=0, membrane_found=0, membrane_iter=0,
67     swit=0, length=0, membrane=-NO, viscoplasti=0,
68     viscoplasti_always=-NO, plasti_type=-NONE, volumetric_young_order=0,
69     memory=-UPDATED, max_plasti_iter=0, total_plasti_iter=0,
70     nuser_data=0, idim=0, jdim=0, kdim=0, ldim=0,
71     formulation=INCREMENTAL, ldum=0, idum[1], task[2];
72   double lambda=0., deps_size=0., lambda_new=0., lambda_previous=0.,
73     tmp=0., tmp_old=0., tmp_inc=0., tmp_new=0.,
74     f=0., f_previous=0, f_ref=0., materi_expansion_linear=0.,
75     eta=0., pressure=0., strain_size=0., straindev_size=0., linear_ept=0.,zero_ept=0.,
76 	 meanstrain=0.,
77     plasti_kinematic_hardening=0., young = 0., young_linear_ept=0., poisson=0.,
78     compressibility=0., fac=0., kappa=0., g=0., k=0., e=0.,
79     lade_1=0., lade_2=0, lade_3=0., p=0., p0=0., young0=0.,
80     alpha=0., gamma=0., dtime=0., rdum=0., camclay[1], tskh[DATA_ITEM_SIZE],
81     smallstrain[6],
82     group_materi_elasti_lade[3], sig_dev[MDIM*MDIM], ddum[MDIM*MDIM], ddumarray[MDIM][MDIM],
83     memmat[MDIM][MDIM], elasti_transverse_isotropy[DATA_ITEM_SIZE],
84     inc_temperature_strain[MDIM*MDIM], new_temperature_strain[MDIM*MDIM],
85     plasti_dir[MDIM*MDIM], young_power[3], young_polynomial[DATA_ITEM_SIZE],
86     young_strainstress[DATA_ITEM_SIZE], ept_dev[MDIM*MDIM],
87     plasti_visco_exponential[2], plasti_visco_power[3],
88     inc_rho[MDIM*MDIM], test_sig[MDIM*MDIM], total_inc_epp[MDIM*MDIM],
89     work_inc_epp[MDIM*MDIM], new_epe[MDIM*MDIM], new_epp[MDIM*MDIM],
90     C[MDIM][MDIM][MDIM][MDIM], Cmem[MDIM][MDIM][MDIM][MDIM],
91     Cuser[MDIM][MDIM][MDIM][MDIM], Chyper[MDIM][MDIM][MDIM][MDIM],
92     Chypo[MDIM][MDIM][MDIM][MDIM],
93     volumetric_young_values[DATA_ITEM_SIZE],
94     user_data[DATA_ITEM_SIZE], work[DATA_ITEM_SIZE],
95     old_work[MDIM*MDIM], new_work[MDIM*MDIM];
96 
97   swit = set_swit(element,-1, "set_stress");
98   if ( swit ) pri( "In routine SET_STRESS" );
99 
100   plasti_visco_exponential[0] = 0.;
101   plasti_visco_power[0] = 0.;
102   if ( get_group_data( GROUP_MATERI_PLASTI_VISCO_EXPONENTIAL, gr, element,
103       new_unknowns, plasti_visco_exponential, ldum, GET_IF_EXISTS ) ) {
104     viscoplasti = 1;
105     gamma = plasti_visco_exponential[0]; alpha = plasti_visco_exponential[1];
106     pressure = ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
107     if ( alpha<=0. || gamma<=0. )
108       db_error(  GROUP_MATERI_PLASTI_VISCO_EXPONENTIAL, gr );
109   }
110   else if ( get_group_data( GROUP_MATERI_PLASTI_VISCO_POWER, gr, element,
111       new_unknowns, plasti_visco_power, ldum, GET_IF_EXISTS ) ) {
112     viscoplasti = 1;
113     eta = plasti_visco_power[0]; p = plasti_visco_power[1];
114     f_ref = plasti_visco_power[2]; assert( f_ref!=0. );
115   }
116 
117   db( DTIME, 0, idum, &dtime, ldum, VERSION_NORMAL, GET_IF_EXISTS );
118   db( GROUP_MATERI_PLASTI_VISCO_ALWAYS, gr, &viscoplasti_always,
119     ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
120   db( GROUP_MATERI_MEMORY, gr, &memory, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
121 
122   array_set( &C[0][0][0][0], 0., MDIM*MDIM*MDIM*MDIM );
123   array_set( &Cmem[0][0][0][0], 0., MDIM*MDIM*MDIM*MDIM );
124   get_group_data( GROUP_MATERI_ELASTI_COMPRESSIBILITY, gr, element, new_unknowns,
125     &compressibility, ldum, GET_IF_EXISTS );
126   db( GROUP_MATERI_MEMBRANE, gr, &membrane, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
127   task[1] = membrane;
128   if ( get_group_data( GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY, gr,
129       element, new_unknowns, elasti_transverse_isotropy, ldum, GET_IF_EXISTS ) ) {
130     task[0] = GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY;
131     task[1] = -NO;
132     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
133     task[1] = membrane;
134     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
135   }
136 
137   task[0] = GROUP_MATERI_ISOTROPY; //always if not changed by TRANSVERSE_ISOTROPY_GRAHOUL
138   if ( get_group_data( GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY_GRAHOUL, gr,
139       element, new_unknowns, elasti_transverse_isotropy, ldum, GET_IF_EXISTS ) ) {
140     task[0] = GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY_GRAHOUL;
141   }
142 
143   if ( get_group_data( GROUP_MATERI_ELASTI_YOUNG, gr, element, new_unknowns,
144       &young, ldum, GET_IF_EXISTS ) ) {
145     get_group_data( GROUP_MATERI_ELASTI_POISSON, gr, element,
146       new_unknowns, &poisson, ldum, GET_IF_EXISTS );
147     task[1] = -NO;
148     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
149     task[1] = membrane;
150     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
151   }
152   if ( get_group_data( GROUP_MATERI_ELASTI_YOUNG_POLYNOMIAL, gr, element, new_unknowns,
153       young_polynomial, length, GET_IF_EXISTS ) ) {
154     strain_size = array_size( new_ept, MDIM*MDIM );
155     young = 0.;
156     for ( i=0; i<length; i++ )
157       young += young_polynomial[i] * scalar_power(strain_size,i);
158     get_group_data( GROUP_MATERI_ELASTI_POISSON, gr, element,
159       new_unknowns, &poisson, ldum, GET_IF_EXISTS );
160     task[1] = -NO;
161     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
162     task[1] = membrane;
163     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
164   }
165   if ( get_group_data( GROUP_MATERI_ELASTI_YOUNG_POWER, gr, element, new_unknowns,
166       young_power, ldum, GET_IF_EXISTS ) ) {
167     get_group_data( GROUP_MATERI_ELASTI_POISSON, gr, element,
168       new_unknowns, &poisson, ldum, GET_IF_EXISTS );
169     p0 = young_power[0];
170     young0 = young_power[1];
171     alpha = young_power[2];
172     if ( p0<=0. ) db_error( GROUP_MATERI_ELASTI_YOUNG_POWER, gr );
173     p = - ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
174     young = young0 * scalar_power(scalar_dabs(p/p0),alpha);
175     task[1] = -NO;
176     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
177     task[1] = membrane;
178     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
179   }
180   if ( get_group_data( GROUP_MATERI_ELASTI_YOUNG_STRAINSTRESS, gr, element, new_unknowns,
181       young_strainstress, length, GET_IF_EXISTS ) ) {
182 
183     meanstrain = ( new_ept[0] + new_ept[4] + new_ept[8] ) / 3.;
184     array_move( new_ept, ept_dev, MDIM*MDIM );
185     for ( idim=0; idim<MDIM; idim++ ) ept_dev[idim*MDIM+idim] -= meanstrain;
186     straindev_size = array_size( ept_dev, MDIM*MDIM );
187 
188     young = 0.;
189 
190     linear_ept=young_strainstress[2];
191     zero_ept=young_strainstress[3];
192 
193     for ( i=5; i<length; i++ )
194     		young_linear_ept += young_strainstress[i] * scalar_power(linear_ept,i-5);
195 
196     if (straindev_size <= linear_ept)
197     	for ( i=5; i<length; i++ )
198     		young += young_strainstress[i] * scalar_power(straindev_size,i-5);
199     else if (straindev_size >= linear_ept && straindev_size <= zero_ept)
200 	young = young_linear_ept*(log10(zero_ept) -
201 	log10(straindev_size))/(log10(zero_ept) - log10(linear_ept));
202     else young = 0;
203 
204     alpha = young_strainstress[0];
205     p0 = young_strainstress[1];
206 
207     if ( p0<=0. ) db_error( GROUP_MATERI_ELASTI_YOUNG_STRAINSTRESS, gr );
208     p = - ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
209     young = young * scalar_power(scalar_dabs(p/p0),alpha);
210 
211     if (new_kappa>0)
212         young=young_strainstress[4]* scalar_power(scalar_dabs(p/p0),alpha);
213 
214     get_group_data( GROUP_MATERI_ELASTI_POISSON, gr, element,
215       new_unknowns, &poisson, ldum, GET_IF_EXISTS );
216     task[1] = -NO;
217     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
218     task[1] = membrane;
219     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
220   }
221   if (
222       db( GROUP_MATERI_ELASTI_VOLUMETRIC_YOUNG_ORDER, gr,
223         &volumetric_young_order, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS ) ||
224       db( GROUP_MATERI_ELASTI_VOLUMETRIC_YOUNG_VALUES, gr, idum,
225         volumetric_young_values, ldum, VERSION_NORMAL, GET_IF_EXISTS )) {
226     get_group_data( GROUP_MATERI_ELASTI_VOLUMETRIC_POISSON, gr, element,
227       new_unknowns, &poisson, ldum, GET_IF_EXISTS );
228     get_group_data( GROUP_MATERI_ELASTI_VOLUMETRIC_YOUNG_VALUES, gr, element,
229       new_unknowns, volumetric_young_values, length, GET );
230     if ( length<4 ) db_error( GROUP_MATERI_ELASTI_VOLUMETRIC_YOUNG_VALUES, gr );
231     if ( !fit_polynomial( volumetric_young_values, length/2, young_polynomial,
232         volumetric_young_order ) ) {
233       pri( "Error detected for GROUP_MATERI_ELASTI_VOLUMETRIC_YOUNG_*" );
234       pri( "Cannot determine polynomial" );
235       exit(TN_EXIT_STATUS);
236     }
237     strain_size = array_size( new_ept, MDIM*MDIM );
238     if ( strain_size>volumetric_young_values[length-2] )
239       strain_size = volumetric_young_values[length-2];
240     young = 0.;
241     for ( i=1; i<volumetric_young_order; i++ ) {
242       young += i * young_polynomial[i] * scalar_power(strain_size,i-1) *
243        (1.+poisson)*(1.-2.*poisson) / ( 1.-poisson);
244     }
245     task[1] = -NO;
246     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
247     task[1] = membrane;
248     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
249   }
250   if ( get_group_data( GROUP_MATERI_ELASTI_CAMCLAY_G, gr, element, new_unknowns,
251       camclay, ldum, GET_IF_EXISTS ) ||
252       get_group_data( GROUP_MATERI_ELASTI_CAMCLAY_POISSON,
253       gr, element, new_unknowns, camclay, ldum, GET_IF_EXISTS ) ) {
254     if(!get_group_data( GROUP_MATERI_PLASTI_CAMCLAY, gr, element,
255       new_unknowns, work, ldum, GET_IF_EXISTS )){
256       get_group_data( GROUP_MATERI_PLASTI_CAMCLAY_INCREMENTAL, gr, element,
257       new_unknowns, work, ldum, GET);
258     }
259     kappa = work[1];
260     e = old_hisv[0];
261     pressure = - ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
262     k = (1.+e)*pressure/kappa;
263     if      ( get_group_data( GROUP_MATERI_ELASTI_CAMCLAY_G, gr, element,
264         new_unknowns, camclay, ldum, GET_IF_EXISTS ) ) {
265       g = camclay[0];
266       poisson = (3.*k-2.*g)/(2.*g+6.*k);
267     }
268     else if ( get_group_data( GROUP_MATERI_ELASTI_CAMCLAY_POISSON, gr, element,
269         new_unknowns, camclay, ldum, GET_IF_EXISTS ) ) {
270       poisson = camclay[0];
271       g = (3./2.) * k * ( 1 - 2.*poisson ) / ( 1. + poisson );
272     }
273     if ( scalar_dabs(poisson)==1. ) {
274       pri( "\nError detected for camclay plasticity." );
275       pri( "Be sure to  specify initial stresses in the NODE_DOF records." );
276       pri( "Specify legal camclay data. (Or maybe your calculations diverged)." );
277       exit(1);
278     }
279     young = 2.*g*(1.+poisson);
280     task[1] = -NO;
281     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
282     task[1] = membrane;
283     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
284   }
285   if ( get_group_data( GROUP_MATERI_ELASTI_LADE, gr, element,
286       new_unknowns, group_materi_elasti_lade, ldum, GET_IF_EXISTS ) ) {
287     lade_1 = group_materi_elasti_lade[0];
288     lade_2 = group_materi_elasti_lade[1];
289     lade_3 = group_materi_elasti_lade[2];
290     pressure = ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
291     array_move( new_sig, sig_dev, MDIM*MDIM );
292     for ( idim=0; idim<MDIM; idim++ ) sig_dev[idim*MDIM+idim] -= pressure;
293     C_matrix_lade( lade_1, lade_2, lade_3, pressure, sig_dev, C );
294     array_move( &C[0][0][0][0], &Cmem[0][0][0][0], MDIM*MDIM*MDIM*MDIM );
295     if ( membrane==-YES ) {
296       cout << "\nError: GROUP_MATERI_ELASTI_LADE not available for membrane stress state.\n";
297       exit(TN_EXIT_STATUS);
298     }
299     if ( get_group_data( GROUP_MATERI_ELASTI_POISSON, gr, element,
300         new_unknowns, &poisson, ldum, GET_IF_EXISTS ) ) {
301       pri( "GROUP_MATERI_ELASTI_POISSON cannot be used with GROUP_MATERI_ELASTI_LADE." );
302       exit(TN_EXIT_STATUS);
303     }
304   }
305 
306 /***********************elastic models added**********************/
307 
308   if ( get_group_data( GROUP_MATERI_ELASTI_TSKH, gr, element, new_unknowns,
309       tskh, length, GET_IF_EXISTS ) ) {
310 
311     if(!get_group_data( GROUP_MATERI_PLASTI_TSKH, gr, element,
312       new_unknowns, work, ldum, GET_IF_EXISTS )) {
313       get_group_data( GROUP_MATERI_PLASTI_AITSKH, gr, element,
314       new_unknowns, work, ldum, GET );
315     }
316 
317     double A = tskh[0];
318     double n= tskh[1];
319     double m_elasti = tskh[2];
320     kappa = work[1];
321     e = old_hisv[0]-1;
322     double p0 = old_hisv[1];
323     if(p0<=0) {
324     	cout<<"error in tskh_elsti"<<endl;
325 	exit(1);
326     }
327 
328     double geo_sigm= - ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
329     if(geo_sigm<=0) geo_sigm=TINY;
330     double R0=2*p0 / geo_sigm;
331     double g = A*scalar_power(geo_sigm, n)*scalar_power(R0, m_elasti);
332     double k = geo_sigm/kappa;
333 
334     if ( task[0]==GROUP_MATERI_ISOTROPY ) {
335       poisson = (3*k - 2*g)/(2*g + 6*k);
336       if(poisson>0.4999) poisson=0.4999;
337       else if(poisson<0.0001) poisson=0.0001;
338       young = 2.*g*(1.+poisson);
339     }
340     else if ( task[0]==GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY_GRAHOUL ) {
341       double alpha=elasti_transverse_isotropy[0];
342       poisson = (k*(3+3*alpha*alpha/2)-g*(1+2*alpha*alpha))/(k*(3+6*alpha)+g*(4*alpha-1));
343       if(poisson>0.4999) poisson=0.4999;
344       else if(poisson<0.0001) poisson=0.0001;
345       young = 3*g*(1+poisson)*(1-2*poisson)/(1-poisson-2*alpha*poisson+alpha*alpha/2);
346     }
347     task[1] = -NO;
348     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
349     task[1] = membrane;
350     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
351   }
352   if ( get_group_data( GROUP_MATERI_ELASTI_SMALLSTRAIN, gr, element, new_unknowns,
353       smallstrain, length, GET_IF_EXISTS ) ) {
354     double A=smallstrain[0];
355     double n=smallstrain[1];
356     double kappa=smallstrain[2];
357     double R=smallstrain[3];
358     double gamma=smallstrain[4];
359     double delta=smallstrain[5];
360 
361     double geo_sigm= - ( new_sig[0] + new_sig[4] + new_sig[8] ) / 3.;
362     if(geo_sigm<=0) geo_sigm=TINY;
363 
364     double geoept[MDIM*MDIM];
365     array_set(geoept, 0, MDIM*MDIM);
366     array_multiply( new_ept, geoept, -1, MDIM*MDIM );
367     double geoeptsJ=0, geoepts=0, geoeptv=0;
368     calc_IJlode(geoept, geoeptv, geoeptsJ, rdum, false, ddumarray, ddumarray, ddumarray);
369     geoepts=geoeptsJ*2/sqrt(3.);
370 
371     double G0 = A*scalar_power(geo_sigm, n);
372     double K0 = geo_sigm/kappa;
373 
374     if(geoepts<R) geoepts = R;
375     if(scalar_dabs(geoeptv) < R) geoeptv = R;
376     double g=G0*scalar_power((R/geoepts),gamma);
377     double k=K0*scalar_power((R/scalar_dabs(geoeptv)),delta);
378 
379     double ct=100;
380     if ( task[0]==GROUP_MATERI_ISOTROPY ) {
381       poisson = (3*k - 2*g)/(2*g + 6*k);
382       if(poisson>0.4999) poisson=0.4999;
383       else if(poisson<0.0001) poisson=0.0001;
384       young = 2.*g*(1.+poisson);
385 
386       double poisson0 = (3*K0 - 2*G0)/(2*G0 + 6*K0);
387       double young0 = 2.*G0*(1.+poisson0);
388       if(young<young0/ct) young=young0/ct;
389     }
390     else if ( task[0]==GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY_GRAHOUL ) {
391       double alpha=elasti_transverse_isotropy[0];
392       poisson = (k*(3+3*alpha*alpha/2)-g*(1+2*alpha*alpha))/(k*(3+6*alpha)+g*(4*alpha-1));
393       if(poisson>0.4999) poisson=0.4999;
394       else if(poisson<0.0001) poisson=0.0001;
395       young = 3*g*(1+poisson)*(1-2*poisson)/(1-poisson-2*alpha*poisson+alpha*alpha/2);
396 
397       double poisson0 = (K0*(3+3*alpha*alpha/2)-G0*(1+2*alpha*alpha))/(K0*(3+6*alpha)+G0*(4*alpha-1));
398       double young0 = 3*G0*(1+poisson0)*(1-2*poisson0)/(1-poisson0-2*alpha*poisson0+alpha*alpha/2);
399       if(young<young0/ct) young=young0/ct;
400     }
401     task[1] = -NO;
402     C_matrix( young, poisson, elasti_transverse_isotropy, C, task );
403     task[1] = membrane;
404     C_matrix( young, poisson, elasti_transverse_isotropy, Cmem, task );
405 
406     if ( materi_history_variables<2 ) {
407       pri( "Error: materi_history_variables should be 2 for GROUP_MATERI_ELASTI_SMALLSTRAIN (G and K for postprocessing)" );
408       exit(TN_EXIT_STATUS);
409     }
410     new_hisv[0]=g;	//store for post-processing
411     new_hisv[1]=k;
412   }
413 
414 /*****************************************************************************/
415 
416   if ( memory==-TOTAL || memory==-TOTAL_PIOLA  || memory==-TOTAL_LINEAR ) {
417     if ( !materi_strain_total  ) formulation = TOTAL;
418     check_unknown( "materi_velocity", YES, CHECK_USAGE_AND_ERROR );
419     check_unknown( "materi_displacement", YES, CHECK_USAGE_AND_ERROR );
420     check_unknown( "materi_stress", YES, CHECK_USAGE_AND_ERROR );
421   }
422   if ( memory==-UPDATED || memory==-UPDATED_WITHOUT_ROTATION ) {
423     check_unknown( "materi_velocity", YES, CHECK_USAGE_AND_ERROR );
424     check_unknown( "materi_displacement", NO, CHECK_USAGE_AND_ERROR );
425     check_unknown( "materi_stress", YES, CHECK_USAGE_AND_ERROR );
426   }
427 
428 
429   db( GROUP_MATERI_PLASTI_KINEMATIC_HARDENING, gr, idum, &plasti_kinematic_hardening,
430     ldum, VERSION_NORMAL, GET_IF_EXISTS );
431   get_group_data( GROUP_USER_DATA, gr, element, new_unknowns, user_data,
432     nuser_data, GET_IF_EXISTS );
433 
434   if ( condif_temperature ) {
435     array_set( inc_temperature_strain, 0., MDIM*MDIM );
436     array_set( new_temperature_strain, 0., MDIM*MDIM );
437     get_group_data( GROUP_MATERI_EXPANSION_LINEAR, gr, element, new_unknowns,
438       &materi_expansion_linear, ldum, GET_IF_EXISTS );
439     for ( idim=0; idim<MDIM; idim++ ) {
440       inc_temperature_strain[idim*MDIM+idim] = -materi_expansion_linear *
441         ( new_unknowns[temp_indx] - old_unknowns[temp_indx] ) ;
442       new_temperature_strain[idim*MDIM+idim] = -materi_expansion_linear *
443         new_unknowns[temp_indx];
444     }
445     if ( swit ) {
446       pri( "inc_temperature_strain", inc_temperature_strain, MDIM, MDIM );
447       pri( "new_temperature_strain", new_temperature_strain, MDIM, MDIM );
448     }
449   }
450 
451   array_set( ddsdde, 0., MSTRAIN*MSTRAIN );
452   array_set( &Cuser[0][0][0][0], 0., MDIM*MDIM*MDIM*MDIM );
453   array_set( &Chyper[0][0][0][0], 0., MDIM*MDIM*MDIM*MDIM );
454   array_set( &Chypo[0][0][0][0], 0., MDIM*MDIM*MDIM*MDIM );
455   array_set( plasti_dir, 0., MDIM*MDIM );
456   array_set( total_inc_epp, 0., MDIM*MDIM );
457   deps_size = array_size( inc_ept, MDIM*MDIM );
458   if ( deps_size<EPS_SIZE ) deps_size = EPS_SIZE;
459 
460   if      ( materi_plasti_f_nonlocal && viscoplasti )
461     max_plasti_iter = 2;
462   else if ( viscoplasti )
463     max_plasti_iter = 10;
464   else
465     max_plasti_iter = MAX_ITER;
466 
467   /*********added for explicit time integration*******************************************/
468 
469   array_move(old_epi, new_epi, MDIM*MDIM);
470 
471   plasti_type = -NONE;
472   //double tmpdoub=0;
473   bool plasti_incremental=false;
474   double plasti_dt[DATA_ITEM_SIZE];
475   for(i=0; i<DATA_ITEM_SIZE; i++) plasti_dt[i]=0;
476   long int length_pl=0, i_points=0, tmp2=0;
477 
478   if(get_group_data( GROUP_MATERI_PLASTI_TSKH,
479   	gr, element, new_unknowns, plasti_dt, length_pl, GET_IF_EXISTS)) {
480   	plasti_type=GROUP_MATERI_PLASTI_TSKH;
481 	plasti_incremental=true;
482   }
483   else if(get_group_data( GROUP_MATERI_PLASTI_AITSKH,
484   	gr, element, new_unknowns, plasti_dt, length_pl, GET_IF_EXISTS)) {
485   	plasti_type=GROUP_MATERI_PLASTI_AITSKH;
486 	plasti_incremental=true;
487   }
488   else if(get_group_data( GROUP_MATERI_PLASTI_CAMCLAY_INCREMENTAL,
489   	gr, element, new_unknowns, plasti_dt, length_pl, GET_IF_EXISTS)) {
490   	plasti_type=GROUP_MATERI_PLASTI_CAMCLAY_INCREMENTAL;
491 	plasti_incremental=true;
492   }
493   if(plasti_incremental) {
494         if (db_active_index( GROUP_INTEGRATION_POINTS, gr, VERSION_NORMAL) )
495 	    db( GROUP_INTEGRATION_POINTS, gr, &i_points, &tmp, tmp2, VERSION_NORMAL, GET );
496 	if((i_points!=-MAXIMAL) && (options_element_dof != -YES)) {
497 	    cout<<"You must set 'options_element_dof -yes'"<<endl;
498 	    cout<<"for explicit time integration"<<endl<<endl;
499 	    exit(1);
500  	}
501 
502   	//interface routine to single element program triax (D.Masin@city.ac.uk)
503         plasti_incr(
504 		/*input*/ rotated_old_sig, inc_ept, old_epp,
505 			new_ept, C, old_hisv, plasti_type,
506 		 	plasti_dt, length_pl, gr, element, softvar_nonl, softvar_l,
507      		/*output*/ new_sig, inc_epp, new_hisv, new_f, new_substeps, Cmem
508 	);
509 	array_add( inc_epp, old_epp, new_epp, MDIM*MDIM );
510 	array_subtract( inc_ept, inc_epp, inc_epe, MDIM*MDIM );
511 	array_add( inc_epe, old_epe, new_epe, MDIM*MDIM );
512 
513         if ( materi_plasti_kappa ) {
514 	  tmp = array_inproduct( inc_epp, inc_epp, MDIM*MDIM );
515 	  new_kappa = old_kappa + sqrt(0.5*tmp);
516 	  if ( swit ) pri( "new_kappa", new_kappa );
517 	}
518   }
519   else {
520 
521   /*********************************************************************************/
522 
523     // plastic iterations
524   while ( !plasti_found && total_plasti_iter<max_plasti_iter ) {
525     plasti_iter++;
526     total_plasti_iter++;
527     if ( swit ) {
528       pri( "plasti_iter", plasti_iter );
529       pri( "total_plasti_iter", total_plasti_iter );
530       pri( "lambda", lambda );
531     }
532       // plastic strain part
533     if ( viscoplasti )
534       array_multiply( plasti_dir, work_inc_epp, lambda*dtime, MDIM*MDIM );
535     else
536       array_multiply( plasti_dir, work_inc_epp, lambda*deps_size, MDIM*MDIM );
537     array_add( work_inc_epp, total_inc_epp, inc_epp, MDIM*MDIM );
538     if ( swit ) pri( "plastic strain increment", inc_epp, MDIM, MDIM );
539 
540       // plasti kappa
541     if ( materi_plasti_kappa ) {
542       tmp = array_inproduct( inc_epp, inc_epp, MDIM*MDIM );
543       new_kappa = old_kappa + sqrt(0.5*tmp);
544       if ( swit ) pri( "new_kappa", new_kappa );
545     }
546 
547       // plasti rho
548     if ( materi_plasti_rho ) {
549       array_multiply( inc_epp, inc_rho,
550         plasti_kinematic_hardening, MDIM*MDIM );
551       array_add( old_rho, inc_rho, new_rho, MDIM*MDIM );
552       if ( swit ) pri( "new_rho", new_rho, MDIM, MDIM );
553     }
554 
555       // new plastic strain
556     array_add( inc_epp, old_epp, new_epp, MDIM*MDIM );
557     if ( swit ) pri( "plastic strain", new_epp, MDIM, MDIM );
558 
559       // elastic strain part in elastic-plastic strain part
560     array_subtract( inc_ept, inc_epp, inc_epe, MDIM*MDIM );
561     array_subtract( new_ept, new_epp, new_epe, MDIM*MDIM );
562     if ( condif_temperature ) {
563       array_add( inc_epe, inc_temperature_strain, inc_epe, MDIM*MDIM );
564       array_add( new_epe, new_temperature_strain, new_epe, MDIM*MDIM );
565     }
566 
567       // membrane iterations
568     membrane_found = membrane_iter = 0;
569     while ( !membrane_found && membrane_iter<MAX_ITER ) {
570       membrane_iter++;
571       if ( swit ) {
572         pri( "membrane_iter", membrane_iter );
573         pri( "inc_epe", inc_epe, MDIM, MDIM );
574         pri( "new_epe", new_epe, MDIM, MDIM );
575       }
576 
577         // elasticity
578       if ( formulation==TOTAL )
579          matrix_a4b( C, new_epe, new_sig );
580       else {
581          matrix_a4b( C, inc_epe, work );
582          array_add( work, rotated_old_sig, new_sig, MDIM*MDIM );
583       }
584       if ( swit ) pri( "stress after elasticity", new_sig, MDIM, MDIM );
585 
586         // membrane stiffness
587       memmat[0][0] = C[0][0][0][0];
588       memmat[0][1] = C[0][0][1][1];
589       memmat[0][2] = C[0][0][2][2];
590       memmat[1][0] = C[1][1][0][0];
591       memmat[1][1] = C[1][1][1][1];
592       memmat[1][2] = C[1][1][2][2];
593       memmat[2][0] = C[2][2][0][0];
594       memmat[2][1] = C[2][2][1][1];
595       memmat[2][2] = C[2][2][2][2];
596 
597         // user supplied
598       user_sigma( user_data, new_unknowns, inc_epe,
599         old_hisv, new_hisv, rotated_old_sig, new_sig, Cuser );
600       stress_umat( element, gr, formulation, nuser_data, user_data, coord_ip,
601         old_hisv, new_hisv, old_unknowns, new_unknowns,
602         inc_ept, new_ept, rotated_old_sig, new_sig,
603         old_deften, new_deften, inc_rot, ddsdde );
604       if ( swit ) pri( "stress after user supplied", new_sig, MDIM, MDIM );
605 
606         // hypoplasticity
607       hypoplasticity( element, gr, formulation,
608         old_hisv, new_hisv, old_unknowns, new_unknowns,
609         inc_ept, old_epi, new_epi, rotated_old_sig,
610         new_sig, &Chypo[0][0][0][0], softvar_nonl, softvar_l );
611       if ( swit ) pri( "stress after hypoplasticity", new_sig, MDIM, MDIM );
612 
613         // compressibility
614       if ( compressibility!=0. ) {
615         if      ( memory==-TOTAL_LINEAR ) {
616           tmp_old = ( old_epe[0] + old_epe[4] + old_epe[8] ) / compressibility;
617           tmp_new = ( new_epe[0] + new_epe[4] + new_epe[8] ) / compressibility;
618           tmp_inc = tmp_new - tmp_old;
619         }
620         else if ( memory==-TOTAL ) {
621           array_move( old_epe, work, MDIM*MDIM );
622           for ( idim=0; idim<MDIM; idim++ ) work[idim*MDIM+idim] += 1.;
623           tmp_old = (matrix_determinant(work,MDIM)-1.) / compressibility;
624           array_move( new_epe, work, MDIM*MDIM );
625           for ( idim=0; idim<MDIM; idim++ ) work[idim*MDIM+idim] += 1.;
626           tmp_new = (matrix_determinant(work,MDIM)-1.) / compressibility;
627           tmp_inc = tmp_new - tmp_old;
628         }
629         else if ( memory==-TOTAL_PIOLA ) {
630           array_move( old_epe, work, MDIM*MDIM );
631           array_multiply( work, work, 2., MDIM*MDIM );
632           for ( idim=0; idim<MDIM; idim++ ) work[idim*MDIM+idim] += 1.;
633           tmp_old = (sqrt(matrix_determinant(work,MDIM))-1.) / compressibility;
634           array_move( new_epe, work, MDIM*MDIM );
635           array_multiply( work, work, 2., MDIM*MDIM );
636           for ( idim=0; idim<MDIM; idim++ ) work[idim*MDIM+idim] += 1.;
637           tmp_new = (sqrt(matrix_determinant(work,MDIM))-1.) / compressibility;
638           tmp_inc = tmp_new - tmp_old;
639         }
640         else {
641           tmp_inc = ( inc_epe[0] + inc_epe[4] + inc_epe[8] ) /  compressibility;
642         }
643         for ( idim=0; idim<MDIM; idim++ ) {
644           if ( formulation==TOTAL ) new_sig[idim*MDIM+idim] += tmp_new;
645           else new_sig[idim*MDIM+idim] += tmp_inc;
646         }
647         if ( swit ) pri( "stress after compressibility", new_sig, MDIM, MDIM );
648       }
649 
650         // hyperelasticity
651       hyperelasticity( gr, element, memory, old_unknowns, old_epe,
652         old_work, Chyper );
653       hyperelasticity( gr, element, memory, new_unknowns, new_epe,
654         new_work, Chyper );
655       if ( formulation==TOTAL )
656         array_move( new_work, work, MDIM*MDIM );
657       else
658         array_subtract( new_work, old_work, work, MDIM*MDIM );
659       array_add( work, new_sig, new_sig, MDIM*MDIM );
660       memmat[0][0] += Chyper[0][0][0][0];
661       memmat[0][1] += Chyper[0][0][1][1];
662       memmat[0][2] += Chyper[0][0][2][2];
663       memmat[1][0] += Chyper[1][1][0][0];
664       memmat[1][1] += Chyper[1][1][1][1];
665       memmat[1][2] += Chyper[1][1][2][2];
666       memmat[2][0] += Chyper[2][2][0][0];
667       memmat[2][1] += Chyper[2][2][1][1];
668       memmat[2][2] += Chyper[2][2][2][2];
669       if ( swit ) pri( "stress after hyperelasticity", new_sig, MDIM, MDIM );
670 
671         // viscosity
672       viscous_stress( element, gr, user_data, old_unknowns,
673         old_grad_old_unknowns, old_work,
674         viscosity, viscosity_heat_generation );
675       viscous_stress( element, gr, user_data, new_unknowns,
676         new_grad_new_unknowns, new_work,
677         viscosity, viscosity_heat_generation );
678       if ( formulation==TOTAL )
679         array_move( new_work, work, MDIM*MDIM );
680       else
681         array_subtract( new_work, old_work, work, MDIM*MDIM );
682       array_add( work, new_sig, new_sig, MDIM*MDIM );
683       if ( swit ) pri( "stress after viscosity", new_sig, MDIM, MDIM );
684 
685         // viscoelasticity
686       visco_elasticity( element, gr, formulation, new_unknowns, inc_epe,
687         rotated_old_msig, new_sig, new_msig, memmat );
688       if ( swit ) pri( "stress after visco elasticity", new_sig, MDIM, MDIM );
689 
690         // damage
691       if ( materi_damage ) {
692         damage( gr, new_epe, new_sig, old_damage, new_damage );
693         array_multiply( new_sig, new_sig, 1.-new_damage, MDIM*MDIM );
694         array_multiply( &memmat[0][0], &memmat[0][0], 1.-new_damage, MDIM*MDIM );
695         if ( swit ) pri( "stress after damage", new_sig, MDIM, MDIM );
696       }
697 
698           // membrane iterations ready?
699       membrane_found = membrane_apply( element, gr, memmat, inc_ept,
700         inc_epe, new_ept, new_epe, new_sig );
701 	//I have always membrane_found==TRUE
702     }
703 
704       // test stresses for plastic yield functions
705     array_move( new_sig, test_sig, MDIM*MDIM );
706     if ( materi_plasti_rho )
707       array_subtract( test_sig, new_rho, test_sig, MDIM*MDIM );
708       // new lambda
709     if ( plasti_iter==1 ) {
710       plasti_type = -NONE; plasti_rule( element, gr, plasti_on_boundary, user_data,
711         new_unknowns, new_grad_new_unknowns, old_hisv, new_hisv,
712         old_epp, inc_epp, inc_ept, GET_YIELD_RULE,
713         plasti_type, test_sig, f, new_f, ddum );
714 
715       if ( materi_plasti_f_nonlocal && viscoplasti ) f = new_unknowns[fn_indx];
716       if ( swit ) {
717         pri( "plasti_iter", plasti_iter );
718         pri( "plasti_type", -plasti_type );
719         pri( "f", f );
720       }
721       //if f is negative, solution is elastic (first iteration->lambda=0)
722       //otherwise plastic iterations start
723       if ( ( f<EPS_F && viscoplasti_always==-NO ) || f==NO_YIELD_F )
724         plasti_found = 1;
725       else {
726         if ( viscoplasti ) {
727           lambda_previous = 0.; f_previous = f;
728           if ( plasti_visco_exponential[0]>0. ) {
729             tmp = alpha*f;
730             if ( tmp>EPS_VISCO ) tmp = EPS_VISCO;
731             lambda = gamma * (-pressure) * exp(tmp);
732           }
733           else {
734             assert( plasti_visco_power[0]>0. );
735             lambda = eta * scalar_power(f/f_ref,p);
736           }
737         }
738         else {
739           lambda_previous = 0.; f_previous = f;
740           lambda = EPS_LAMBDA;
741         }
742         plasti_rule( element, gr, plasti_on_boundary, user_data,
743           new_unknowns, new_grad_new_unknowns,
744           old_hisv, new_hisv, old_epp, inc_epp, inc_ept,
745           GET_FLOW_RULE_GRAD, plasti_type, test_sig, rdum, rdum, plasti_dir );
746         if ( !viscoplasti ) array_normalize( plasti_dir, MDIM*MDIM );
747         if ( swit ) pri( "plasti_dir", plasti_dir, MDIM*MDIM );
748       }
749     }
750     else {
751       plasti_rule( element, gr, plasti_on_boundary, user_data, new_unknowns, new_grad_new_unknowns,
752         old_hisv, new_hisv, old_epp, inc_epp, inc_ept, GET_YIELD_RULE, plasti_type,
753         test_sig, f, new_f, ddum );
754       if ( materi_plasti_f_nonlocal && viscoplasti ) f = new_unknowns[fn_indx];
755       if ( f>DBL_MAX/1.e6 ) {
756         pri( "Error detected in plasticity." );
757         pri( "Maybe too large time steps. Try smaller time steps." );
758         exit(TN_EXIT_STATUS);
759       }
760       if ( swit ) {
761         pri( "plasti_iter", plasti_iter );
762         pri( "plasti_type", plasti_type );
763         pri( "lambda", lambda );
764         pri( "f", f );
765       }
766       if ( scalar_dabs(f)<EPS_F || scalar_dabs(f-f_previous)<EPS_EPS_F*EPS_F ) {
767         array_add( work_inc_epp, total_inc_epp, total_inc_epp, MDIM*MDIM );
768         plasti_type = -NONE; plasti_rule( element, gr, plasti_on_boundary, user_data,
769           new_unknowns, new_grad_new_unknowns, old_hisv, new_hisv,
770           old_epp, inc_epp, inc_ept, GET_YIELD_RULE,
771           plasti_type, test_sig, f, new_f, ddum );
772         if ( f<EPS_F )
773           plasti_found = 1;
774         else {
775           plasti_iter = 0; lambda = 0.;
776         }
777       }
778       else if ( viscoplasti ) {
779         lambda_previous = lambda; f_previous = f;
780         if ( plasti_visco_exponential[0]>0. ) {
781           tmp = alpha*f;
782           if ( tmp>EPS_VISCO ) tmp = EPS_VISCO;
783           lambda = gamma * (-pressure) * exp(tmp);
784         }
785         else {
786           assert( plasti_visco_power[0]>0. );
787           lambda = eta * scalar_power(f/f_ref,p);
788         }
789       }
790       else {
791         if      ( f>f_previous || f<0. ) {
792             // adjust steps if f becomes larger
793           lambda = ( 0.5 * lambda + 0.5 * lambda_previous );
794         }
795         else {
796           tmp = - (lambda-lambda_previous)*f_previous/(f-f_previous);
797           if ( deps_size>EPS_SIZE ) {
798             if ( tmp>EPS_TMP ) tmp = EPS_TMP;
799             if ( tmp<-EPS_TMP ) tmp = -EPS_TMP;
800           }
801           lambda_new = lambda_previous + tmp;
802           lambda_previous = lambda; f_previous = f;
803           lambda = lambda_new;
804         }
805       }
806     }
807   }
808   }
809 
810     // fill material stiffness, we use the linear stiffness
811   for ( idim=0; idim<MDIM; idim++ ) {
812     for ( jdim=idim; jdim<MDIM; jdim++ ) {
813       for ( kdim=0; kdim<MDIM; kdim++ ) {
814         for ( ldim=kdim; ldim<MDIM; ldim++ ) {
815           if ( kdim==ldim )
816             fac = 1.0;
817           else
818             fac = 0.5;
819           i = stress_indx(idim,jdim);
820           j = stress_indx(kdim,ldim);
821           ind_ddsdde = i*MSTRAIN+j;
822           ddsdde[ind_ddsdde] += fac * ( Cmem[idim][jdim][kdim][ldim]
823             + Cuser[idim][jdim][kdim][ldim] + Chyper[idim][jdim][kdim][ldim]
824             + Chypo[idim][jdim][kdim][ldim] );
825           if ( compressibility!=0. && idim==jdim && kdim==ldim )
826             ddsdde[ind_ddsdde] += 1./compressibility;
827         }
828       }
829     }
830   }
831 
832   if ( swit ) {
833     pri( "plasti_found", plasti_found );
834     pri( "membrane_found", membrane_found );
835     pri( "stress", new_sig, MDIM, MDIM );
836     pri( "ddsdde", ddsdde, MSTRAIN, MSTRAIN );
837     pri( "Out routine SET_STRESS" );
838   }
839 }
840 
stress_umat(long int element,long int gr,long int formulation,long int nuser_data,double user_data[],double coord_ip[],double old_hisv[],double new_hisv[],double old_unknowns[],double new_unknowns[],double inc_ept[],double new_ept[],double rotated_old_sig[],double new_sig[],double old_deften[],double new_deften[],double inc_rot[],double ddsdde[])841 void stress_umat( long int element, long int gr, long int formulation,
842   long int nuser_data, double user_data[], double coord_ip[],
843   double old_hisv[], double new_hisv[],
844   double old_unknowns[], double new_unknowns[],
845   double inc_ept[], double new_ept[],
846   double rotated_old_sig[], double new_sig[],
847   double old_deften[], double new_deften[],
848   double inc_rot[], double ddsdde[] )
849 
850   /* Interface routine to umat routine. */
851 
852 {
853   double stress[MSTRAIN], statev[DATA_ITEM_SIZE],
854    sse[1], spd[1], scd[1], rpl[1], ddsddt[1], drplde[1], drpldt[1],
855    stran[MSTRAIN], dstran[MSTRAIN], time[1], dtime[1], temp[1], dtemp[1],
856    predef[1], dpred[1];
857   char cmname[1];
858   long int ndi[1], nshr[1], ntens[1], nstatv[1];
859   double props[DATA_ITEM_SIZE];
860   long int nprops[1];
861   double coords[MDIM], drot[MDIM*MDIM], pnewdt[1], celent[1],
862     dfgrd0[MDIM*MDIM], dfgrd1[MDIM*MDIM];
863   long int noel[1], npt[1], layer[1], kspt[1], kstep[1], kinc[1];
864   short cmname_len;
865 
866   long int icontrol=0, number_of_iterations=0, ldum=0, user_umat=-NO, idum[1];
867   long int istrain=0, jstrain=0, idim=0, jdim=0, kdim=0, ldim=0, i=0, j=0,
868     ind_ddsdde=0, abaqus_indx[MSTRAIN][2];
869   double ddum[1], ddsdde_tmp[MSTRAIN*MSTRAIN];
870 
871   db( NUMBER_ITERATIONS, 0, &number_of_iterations, ddum, ldum, VERSION_NEW, GET );
872   db( ICONTROL, 0, &icontrol, ddum, ldum, VERSION_NORMAL, GET );
873   db( GROUP_USER_UMAT, gr, &user_umat, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
874   if ( user_umat==-YES ) {
875 
876       // dummies
877 
878     pnewdt[0] = 0.;
879     celent[0] = 0.;
880     sse[0] = 0.;
881     spd[0] = 0.;
882     scd[0] = 0.;
883     rpl[0] = 0.;
884     ddsddt[0] = 0.;
885     drplde[0]= 0.;
886     drpldt[0] = 0.;
887     predef[0] = 0.;
888     dpred[0] = 0.;
889     npt[0] = 0;
890     layer[0] = 0;
891     kspt[0] = 0;
892     kstep[0] = icontrol;
893     kinc[0] = number_of_iterations;
894     cmname_len = 0;
895 
896       // real data
897 
898     array_move( coord_ip, coords, ndim );
899 
900     noel[0] = element;
901 
902     db( DTIME, 0, idum, dtime, ldum, VERSION_NEW, GET );
903     db( TIME_CURRENT, 0, idum, time, ldum, VERSION_NORMAL, GET );
904 
905     if ( condif_temperature ) {
906       temp[0] = old_unknowns[temp_indx];
907       dtemp[0] = new_unknowns[temp_indx] - old_unknowns[temp_indx];
908     }
909     else {
910       temp[0] = 0.;
911       dtemp[0] = 0.;
912     }
913 
914     nprops[0] = nuser_data;
915     nstatv[0] = materi_history_variables;
916     ndi[0] = 3;
917     nshr[0] = 3;
918     ntens[0] = 6;
919 
920     array_set( ddsdde_tmp, 0., MSTRAIN*MSTRAIN );
921 
922     array_move( user_data, props, nprops[0] );
923 
924     array_move( old_hisv, statev, nstatv[0] );
925 
926     stress[0] = rotated_old_sig[0];
927     stress[1] = rotated_old_sig[4];
928     stress[2] = rotated_old_sig[8];
929     stress[3] = rotated_old_sig[1];
930     stress[4] = rotated_old_sig[2];
931     stress[5] = rotated_old_sig[5];
932 
933     stran[0] = new_ept[0] - inc_ept[0];
934     stran[1] = new_ept[4] - inc_ept[4];
935     stran[2] = new_ept[8] - inc_ept[8];
936     stran[3] = 2. * ( new_ept[1] - inc_ept[1] );
937     stran[4] = 2. * ( new_ept[2] - inc_ept[2] );
938     stran[5] = 2. * ( new_ept[5] - inc_ept[5] );
939 
940     dstran[0] = inc_ept[0];
941     dstran[1] = inc_ept[4];
942     dstran[2] = inc_ept[8];
943     dstran[3] = 2. * inc_ept[1];
944     dstran[4] = 2. * inc_ept[2];
945     dstran[5] = 2. * inc_ept[5];
946 
947     for ( i=0; i<MDIM*MDIM; i++ ) {
948       drot[i] = inc_rot[i];
949       dfgrd0[i] = old_deften[i];
950       dfgrd1[i] = new_deften[i];
951     }
952 
953       // stress contribution by umat
954     umat_( stress, statev, ddsdde_tmp, sse, spd, scd, rpl, ddsddt,
955       drplde, drpldt, stran, dstran, time, dtime, temp, dtemp, predef,
956       dpred, cmname, ndi, nshr, ntens, nstatv, props, nprops, coords, drot,
957       pnewdt, celent, dfgrd0, dfgrd1, noel, npt, layer,
958       kspt, kstep, kinc, cmname_len );
959 
960       // from abaqus fortran to tochnog c++
961     abaqus_indx[0][0] = 0;
962     abaqus_indx[0][1] = 0;
963     abaqus_indx[1][0] = 1;
964     abaqus_indx[1][1] = 1;
965     abaqus_indx[2][0] = 2;
966     abaqus_indx[2][1] = 2;
967     abaqus_indx[3][0] = 0;
968     abaqus_indx[3][1] = 1;
969     abaqus_indx[4][0] = 0;
970     abaqus_indx[4][1] = 2;
971     abaqus_indx[5][0] = 1;
972     abaqus_indx[5][1] = 2;
973     for ( istrain=0; istrain<MSTRAIN; istrain++ ) {
974       idim = abaqus_indx[istrain][0];
975       jdim = abaqus_indx[istrain][1];
976       i = stress_indx(idim,jdim);
977       for ( jstrain=0; jstrain<MSTRAIN; jstrain++ ) {
978         kdim = abaqus_indx[jstrain][0];
979         ldim = abaqus_indx[jstrain][1];
980         j = stress_indx(kdim,ldim);
981         ind_ddsdde = i*MSTRAIN+j;
982         ddsdde[ind_ddsdde] += ddsdde_tmp[jstrain*MSTRAIN+istrain];
983       }
984     }
985 
986     array_move( statev, new_hisv, nstatv[0] );
987 
988     if ( formulation==TOTAL ) {
989       new_sig[0] += stress[0];
990       new_sig[4] += stress[1];
991       new_sig[8] += stress[2];
992       new_sig[1] += stress[3];
993       new_sig[3] += stress[3];
994       new_sig[2] += stress[4];
995       new_sig[6] += stress[4];
996       new_sig[5] += stress[5];
997       new_sig[7] += stress[5];
998     }
999     else {
1000       assert( formulation==INCREMENTAL );
1001       new_sig[0] += stress[0] - rotated_old_sig[0];
1002       new_sig[4] += stress[1] - rotated_old_sig[4];
1003       new_sig[8] += stress[2] - rotated_old_sig[8];
1004       new_sig[1] += stress[3] - rotated_old_sig[1];
1005       new_sig[3] += stress[3] - rotated_old_sig[3];
1006       new_sig[2] += stress[4] - rotated_old_sig[2];
1007       new_sig[6] += stress[4] - rotated_old_sig[6];
1008       new_sig[5] += stress[5] - rotated_old_sig[5];
1009       new_sig[7] += stress[5] - rotated_old_sig[7];
1010     }
1011 
1012   }
1013 
1014 }
1015