/*
    Copyright (C) 1998  Dennis Roddeman

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <fstream.h>
#include <iomanip.h>
#include <iostream.h>
#include <math.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "f2c.h"

  // version stuff: NODE and ELEMENT data can have more versions (i.e. meshes)
#define MVERSION 8 // maximum number of versions
#define VERSION_NORMAL 0 // time=t
#define VERSION_START 1 // time=start_time
#define VERSION_NEW 2 // time=t+dt
#define VERSION_TMP 3 // trash version used by several routines
#define VERSION_NEW_MESH_TMP 4 // trash version used by new_mesh
#define VERSION_NEW_MESH_GENERATED 5 // generated mesh in new_mesh
#define VERSION_PRINT 6 // tempory mesh for printing
#define VERSION_MACRO 7 // tempory mesh for control_macro

  // constants
#define MCHAR 100  // maximum length of names
#define MDIM 3 // maximum number of space dimensions
#define MNOL 27 // maximum number of nodes in an element
#define MSTRAIN 6 // maximum number of strain components
#define MTENDON 20 // maximum number of tendons in an element
#define MTYPE 10 // maximum number of types
#define MCALCUL 10 // maximum length of calcul records
#define MRANGE 1000 // maximum expanded range length
#define MMAXWELL 100 // maximum number of maxwell chains
#define MTHREAD 100 // maximum number of threads
#define MAXIMUM_NODE 125 // always 125
#define DATA_ITEM_SIZE 120 // maximum length of (almost all) records
#define EPS_ISO 1.e-9  // epsilon for isoparametric coordinates
#define EPS_COORD 1.e-9 // epsilon for coordinates
#define EPS_VOLUME 1.e-6 // epsilon for element volume
#define PIRAD 3.1415929794311523
#define MPOINT MNOL // maximum number of integration points in an element, always MNOL
#define MUKNWN DATA_ITEM_SIZE // maximum number of unknowns
#define MPUKNWN DATA_ITEM_SIZE // maximum number of primary unknowns
#define MPRINC MPUKNWN // maximum number of principal unknowns
#define TN_EXIT_STATUS 0

  // database items + others
#define ADD  1
#define ALL  2
#define AREA  3
#define AREA_ELEMENT_GROUP  4
#define AREA_NODE_BOUNDARY  5
#define AVERAGE  6
#define BAR  7
#define BAR2  8
#define BAR3  9
#define BAR4  10
#define BAR5  11
#define BOUNDA  12
#define BOUNDA_FORCE  13
#define BOUNDA_SINE  14
#define BOUNDA_TIME  15
#define BOUNDA_TIME_FILE  16
#define BOUNDA_UNKNOWN  17
#define BRICK  18
#define BUCKLING  19
#define CHANGE  20
#define CHECK  21
#define CHECK_INDEX  22
#define CHECK_NUMBER  23
#define CHECK_USAGE  24
#define CHECK_USAGE_AND_ERROR  25
#define CIRCLE  26
#define CIRCLE_HOLLOW  27
#define CONDIF  28
#define CONDIF_CONVECTION  29
#define CONDIF_CONVECTION_GEOMETRY  30
#define CONDIF_RADIATION  31
#define CONDIF_RADIATION_GEOMETRY  32
#define CONDIF_TEMPERATURE  33
#define CONTACT  34
#define CONTACT_FRICTION  35
#define CONTACT_GEOMETRY  36
#define CONTACT_GEOMETRY_SWITCH  37
#define CONTACT_HEAT_GENERATION  38
#define CONTACT_PENALTY_PRESSURE  39
#define CONTACT_PENALTY_TEMPERATURE  40
#define CONTACT_PENALTY_VELOCITY  41
#define CONTROL  42
#define CONTROL_DATA_DELETE  43
#define CONTROL_DATA_PUT  44
#define CONTROL_DATA_PUT_DOUBLE  45
#define CONTROL_DATA_PUT_INTEGER  46
#define CONTROL_EIGEN  47
#define CONTROL_EIGEN_SCALE  48
#define CONTROL_EIGEN_VALUES  49
#define CONTROL_MESH_ADJUST_GEOMETRY  50
#define CONTROL_MESH_DELETE_GEOMETRY  51
#define CONTROL_MESH_MACRO  52
#define CONTROL_MESH_MACRO_PARAMETERS  53
#define CONTROL_MESH_MERGE  54
#define CONTROL_MESH_NEW_MESH  55
#define CONTROL_MESH_NEW_MESH_ELEMENT  56
#define CONTROL_MESH_NEW_MESH_REGION  57
#define CONTROL_MESH_REFINE_GLOBALLY  58
#define CONTROL_MESH_REFINE_GLOBALLY_GEOMETRY  59
#define CONTROL_MESH_REFINE_LOCALLY  60
#define CONTROL_MESH_REFINE_LOCALLY_GEOMETRY  61
#define CONTROL_MESH_REFINE_LOCALLY_MINIMUM  62
#define CONTROL_MESH_REFINE_LOCALLY_NOT  63
#define CONTROL_MESH_REFINE_LOCALLY_ONLY  64
#define CONTROL_MESH_REFINE_LOCALLY_UNKNOWN  65
#define CONTROL_MESH_REMESH  66
#define CONTROL_MESH_REMESH_FACTOR  67
#define CONTROL_MESH_RENUMBER  68
#define CONTROL_MESH_SPLIT  69
#define CONTROL_PRINT  70
#define CONTROL_PRINT_DATABASE  71
#define CONTROL_PRINT_DATA_VERSUS_DATA  72
#define CONTROL_PRINT_GMV  73
#define CONTROL_PRINT_GMV_MESH  74
#define CONTROL_PRINT_HISTORY  75
#define CONTROL_PRINT_MATLAB  76
#define CONTROL_PRINT_PLOTMTV  77
#define CONTROL_PRINT_PLOTMTV_MESH  78
#define CONTROL_PRINT_TECPLOT  79
#define CONTROL_PRINT_TECPLOT_MESH  80
#define CONTROL_PRINT_VTK  81
#define CONTROL_RELAXATION_CONDIF_TEMPERATURE  82
#define CONTROL_RELAXATION_GROUNDFLOW_PRESSURE  83
#define CONTROL_RELAXATION_MATERI_VELOCITY  84
#define CONTROL_RELAXATION_WAVE_FSCALAR  85
#define CONTROL_REPEAT  86
#define CONTROL_REPEAT_UNTIL_ITEM  87
#define CONTROL_REPEAT_UNTIL_TOLERANCE  88
#define CONTROL_REPEAT_UNTIL_VALUE  89
#define CONTROL_RESTART  90
#define CONTROL_SKIP_CONVECTIVE_PART  91
#define CONTROL_SKIP_INERTIA_CONDIF_TEMPERATURE  92
#define CONTROL_SKIP_INERTIA_GROUNDFLOW_PRESSURE  93
#define CONTROL_SKIP_INERTIA_MATERI_VELOCITY  94
#define CONTROL_SKIP_INERTIA_WAVE_FSCALAR  95
#define CONTROL_SKIP_SPATIAL_STABILIZATION  96
#define CONTROL_SOLVER  97
#define CONTROL_TIMESTEP  98
#define CONTROL_TIMESTEP_ITERATIONS  99
#define CONTROL_TIMESTEP_ITERATIONS_AUTOMATIC  100
#define CYLINDER_HOLLOW  101
#define DATABASE  102
#define DELETE  103
#define DEPENDENCY  104
#define DEPENDENCY_DIAGRAM  105
#define DEPENDENCY_ITEM  106
#define DIAGONAL  107
#define DOF  108
#define DOF_LABEL  109
#define DOF_PRINCIPAL  110
#define DOF_SCAL_VEC_MAT  111
#define DOF_TYINGS  112
#define DOF_TYPE  113
#define DOUBLE  114
#define DTIME  115
#define ELEMENT  116
#define ELEMENT_DELETE_FACTOR  117
#define ELEMENT_GROUP  118
#define ELEMENT_MATRIX_STRESS_STIFFNESS_VALUES  119
#define ELEMENT_MATRIX_UNKNOWNS  120
#define ELEMENT_MATRIX_VALUES  121
#define ELEMENT_TENDON_DIRECTION  122
#define ELEMENT_TENDON_NUMBER  123
#define ELEMENT_TENDON_STRESS  124
#define ELEMENT_TENDON_VOLUME  125
#define ELEMENT_VOLUME  126
#define EMPTY  127
#define EVERYTHING  128
#define FORCE  129
#define FORCE_ELEMENT_EDGE  130
#define FORCE_ELEMENT_EDGE_GEOMETRY  131
#define FORCE_ELEMENT_EDGE_TIME  132
#define FORCE_ELEMENT_VOLUME  133
#define FORCE_ELEMENT_VOLUME_FACTOR  134
#define FORCE_ELEMENT_VOLUME_GEOMETRY  135
#define FORCE_ELEMENT_VOLUME_TIME  136
#define FORCE_GRAVITY  137
#define FORCE_GRAVITY_TIME  138
#define FROM  139
#define GEOMETRY  140
#define GEOMETRY_BOUNDA_FACTOR  141
#define GEOMETRY_CIRCLE  142
#define GEOMETRY_CYLINDER  143
#define GEOMETRY_LINE  144
#define GEOMETRY_POINT  145
#define GEOMETRY_POLYNOMIAL  146
#define GEOMETRY_QUADRILATERAL  147
#define GEOMETRY_SET  148
#define GEOMETRY_SPHERE  149
#define GEOMETRY_TRIANGLE  150
#define GET  151
#define GET_AND_CHECK  152
#define GET_FLOW_RULE  153
#define GET_FLOW_RULE_GRAD  154
#define GET_IF_EXISTS  155
#define GET_YIELD_RULE  156
#define GROUNDFLOW  157
#define GROUNDFLOW_PRESSURE  158
#define GROUNDFLOW_VELOCITY  159
#define GROUP_CONDIF_ABSORPTION  160
#define GROUP_CONDIF_CAPACITY  161
#define GROUP_CONDIF_CONDUCTIVITY  162
#define GROUP_CONDIF_DENSITY  163
#define GROUP_CONDIF_FLOW  164
#define GROUP_GROUNDFLOW_COMPRESSIBILITY  165
#define GROUP_GROUNDFLOW_DENSITY  166
#define GROUP_GROUNDFLOW_PERMEABILITY  167
#define GROUP_INTEGRATION_POINTS  168
#define GROUP_MATERI_DAMAGE_FAILURE  169
#define GROUP_MATERI_DAMAGE_MAZARS  170
#define GROUP_MATERI_DAMPING  171
#define GROUP_MATERI_DENSITY  172
#define GROUP_MATERI_DENSITY_MINIMUM  173
#define GROUP_MATERI_ELASTI_COMPRESSIBILITY  174
#define GROUP_MATERI_ELASTI_POISSON  175
#define GROUP_MATERI_ELASTI_TRANSVERSE_ISOTROPY  176
#define GROUP_MATERI_ELASTI_YOUNG  177
#define GROUP_MATERI_EXPANSION_LINEAR  178
#define GROUP_MATERI_EXPANSION_VOLUME  179
#define GROUP_MATERI_HYPER_BESSELING  180
#define GROUP_MATERI_HYPER_MOONEY_RIVLIN  181
#define GROUP_MATERI_MAXWELL_CHAIN  182
#define GROUP_MATERI_MEMBRANE  183
#define GROUP_MATERI_MEMORY  184
#define GROUP_MATERI_PLASTI_COMPRESSION  185
#define GROUP_MATERI_PLASTI_DRUCKPRAG  186
#define GROUP_MATERI_PLASTI_DRUCKPRAG_APEX  187
#define GROUP_MATERI_PLASTI_GURSON  188
#define GROUP_MATERI_PLASTI_HEAT_GENERATION  189
#define GROUP_MATERI_PLASTI_KINEMATIC_HARDENING  190
#define GROUP_MATERI_PLASTI_MOHRCOUL  191
#define GROUP_MATERI_PLASTI_MOHRCOUL_01  192
#define GROUP_MATERI_PLASTI_MOHRCOUL_12  193
#define GROUP_MATERI_PLASTI_MOHRCOUL_20  194
#define GROUP_MATERI_PLASTI_MOHRCOUL_APEX  195
#define GROUP_MATERI_PLASTI_TENSION  196
#define GROUP_MATERI_PLASTI_USER  197
#define GROUP_MATERI_PLASTI_VISCO  198
#define GROUP_MATERI_PLASTI_VONMISES  199
#define GROUP_MATERI_STOKES  200
#define GROUP_MATERI_STRAIN_PLASTI_FAILURE  201
#define GROUP_MATERI_STRAIN_TOTAL_FAILURE  202
#define GROUP_MATERI_VISCOSITY  203
#define GROUP_TYPE  204
#define GROUP_USER_DATA  205
#define GROUP_USER_UMAT  206
#define GROUP_WAVE_SPEED_OF_SOUND  207
#define HEX125  208
#define HEX27  209
#define HEX64  210
#define HEX8  211
#define H_REFINEMENT  212
#define ICONTROL  213
#define INITIALIZATION_VALUES  214
#define INTEGER  215
#define INVERSE  216
#define INVERSE_DETERMINE_NEW_ESTIMATES  217
#define INVERSE_DETERMINE_SENSITIVITY  218
#define INVERSE_HISTORY  219
#define INVERSE_ITERATIONS  220
#define INVERSE_ITERATION_NUMBER  221
#define INVERSE_PARAMETER  222
#define INVERSE_PARAMETER_LIMITS  223
#define INVERSE_PARAMETER_SENSITIVITY  224
#define INVERSE_PARAMETER_SET  225
#define INVERSE_PARAMETER_STEP  226
#define INVERSE_PARAMETER_VARIATION  227
#define INVERSE_TARGET  228
#define INVERSE_TARGET_DATA  229
#define INVERSE_TARGET_TIMESTEP  230
#define MATERI  231
#define MATERI_DAMAGE  232
#define MATERI_DENSITY  233
#define MATERI_DISPLACEMENT  234
#define MATERI_HISTORY_VARIABLES  235
#define GROUP_MATERI_ISOTROPY  236
#define MATERI_MAXWELL_STRESS  237
#define MATERI_PLASTI_KAPPA  238
#define MATERI_PLASTI_RHO  239
#define MATERI_STRAIN_ELASTI  240
#define MATERI_STRAIN_PLASTI  241
#define MATERI_STRAIN_TOTAL  242
#define MATERI_STRESS  243
#define MATERI_VELOCITY  244
#define MATERI_VOID_FRACTION  245
#define MATRIX  246
#define MATRIX_DIRECT  247
#define MATRIX_ITERATIVE  248
#define MAXIMAL  249
#define MESH  250
#define MINIMAL  251
#define NEGATIVE  252
#define NO  253
#define NODE  254
#define NODE_BOUNDARY  255
#define NODE_BOUNDED  256
#define NODE_DAMPING  257
#define NODE_DOF  258
#define NODE_DOF_CALCUL  259
#define NODE_DOF_START_REFINED  260
#define NODE_DOF_TMP  261
#define NODE_EIGEN  262
#define NODE_LHSIDE  263
#define NODE_LOCATE  264
#define NODE_MASS  265
#define NODE_NEL  266
#define NODE_NODE  267
#define NODE_REMESH_VELOCITY  268
#define NODE_RHSIDE  269
#define NODE_RHSIDE_INTERNAL  270
#define NODE_RHSIDE_STATIC  271
#define NODE_START_REFINED  272
#define NODE_TYINGS  273
#define NODE_TYINGS_FACTORS  274
#define NODE_TYINGS_UNKNOWNS  275
#define NONE  276
#define NOTHING  277
#define NUMBER  278
#define NUMBER_ITERATIONS  279
#define OPTIONS_AXISYMMETRIC  280
#define OPTIONS_PROCESSORS  281
#define OPTIONS_RESIDUEFACTOR  282
#define PHIMOB  283
#define PLUS_DISPLACEMENT  284
#define POSITIVE  285
#define POST  286
#define POST_CALCUL  287
#define POST_CALCUL_SCAL_VEC_MAT  288
#define POST_ERROR_ITEM  289
#define POST_ERROR_MESH1  290
#define POST_ERROR_MESH2  291
#define POST_ERROR_RESULT  292
#define POST_LINE  293
#define POST_LINE_DOF  294
#define POST_LINE_DOF_CALCUL  295
#define POST_LINE_MOMENT  296
#define POST_LINE_N  297
#define POST_NODE  298
#define POST_NODE_RESULT  299
#define POST_NODE_RHSIDE_FIXED  300
#define POST_NODE_RHSIDE_FREE  301
#define POST_NODE_RHSIDE_RATIO  302
#define POST_POINT  303
#define POST_POINT_DOF  304
#define POST_POINT_DOF_CALCUL  305
#define POST_QUADRILATERAL  306
#define POST_QUADRILATERAL_DOF  307
#define POST_QUADRILATERAL_DOF_CALCUL  308
#define POST_QUADRILATERAL_N  309
#define PRINT  310
#define PRINT_FILTER  311
#define PRIVAL  312
#define PRIVEC  313
#define PROJECT_EXACT  314
#define PROJECT_ON_EDGE  315
#define PUT  316
#define P_COARSEN  317
#define P_REFINEMENT  318
#define QUAD16  319
#define QUAD25  320
#define QUAD4  321
#define QUAD9  322
#define RA  323
#define RECTANGLE  324
#define RESIDUE  325
#define SCALAR  326
#define SIZE  327
#define SIZEDEV  328
#define SLIDE  329
#define SLIDE_FRICTION  330
#define SLIDE_GEOMETRY  331
#define SPHERE  332
#define STEP  333
#define SUM  334
#define TARGET  335
#define TARGET_ITEM  336
#define TARGET_VALUE  337
#define TENDON  338
#define TENDON_ELASTI  339
#define TENDON_EXPANSION  340
#define TENDON_PLASTI  341
#define TENDON_SPLIT  342
#define TENDON_SPLIT_ELEMENT  343
#define TENDON_STRESS  344
#define TET4  345
#define TIME  346
#define TIME_AT_START  347
#define TIME_CURRENT  348
#define TIME_NEW  349
#define TIME_CALCULATION  350
#define TIME_OLD  351
#define TO  352
#define TOTAL  353
#define TRIA3  354
#define TYINGS  355
#define UPDATED  356
#define UPDATED_WITHOUT_ROTATION  357
#define USER  358
#define VALUE  359
#define VECTOR  360
#define VOLUME  361
#define VOLUME_ELEMENT_FACTOR  362
#define VOLUME_FACTOR  363
#define WAVE  364
#define WAVE_FSCALAR  365
#define WAVE_SCALAR  366
#define POST_CALCUL_UNKNOWN_OPERAT  367
#define YES  368
#define MDAT YES+DATA_ITEM_SIZE  // reserve space for unknowns

  // see initialization part in manual
extern long int echo, ndim, derivatives, condif_temperature, 
  groundflow_gvelocity, groundflow_pressure, materi_history_variables,
  materi_damage, materi_density, materi_displacement, 
  materi_maxwell_stress, materi_plasti_kappa, materi_plasti_rho, 
  materi_strain_elasti, materi_strain_plasti, materi_strain_total, 
  materi_stress, materi_velocity, materi_void_fraction,
  residue, wave_scalar, wave_fscalar; 

  // for internal use
extern long int
  nder, // number of derivatives (incl. primary unknown itself)
  npuknwn, // number of primary unknowns
  nuknwn, // number of unknowns (= npuknwn*nder)
  nprinc, // number of principal unknowns
  dam_indx, // index stating start of materi_damage in node_dof
  dens_indx, // index stating start of materi_density in node_dof
  dis_indx, // index stating start of materi_displacement in node_dof
  epe_indx, // index stating start of materi_strain_elasti in node_dof
  epp_indx, // index stating start of materi_strain_plasti in node_dof
  ept_indx, // index stating start of materi_strain_total in node_dof
  gvel_indx, // index stating start of groundflow_gvelocity in node_dof
  hisv_indx, // index stating start of materi_history_variables in node_dof
  mstres_indx, // index stating start of materi_maxwell stress in node_dof
  pres_indx, // index stating start of groundflow_pressure in node_dof
  res_indx, // index stating start of residue in node_dof
  kap_indx, // index stating start of materi_plasti_kappa in node_dof
  rho_indx, // index stating start of materi_plasti_rho in node_dof
  scal_indx, // index stating start of wave_scalar in node_dof
  stres_indx, // index stating start of materi_stress in node_dof
  temp_indx, // index stating start of condif_temperature in node_dof
  fscal_indx, // index stating start of wave_fscalar in node_dof
  vel_indx, // index stating start of materi_velocity in node_dof
  void_indx; // index stating start of materi_void_fraction in node_dof
extern char
  data_file[MCHAR], // data file name
  data_file_base[MCHAR], // data file name base
  last_routine[MCHAR], // last routine called
  post_calcul_names[DATA_ITEM_SIZE][MCHAR], // names for calcul
  initialization_names[DATA_ITEM_SIZE][MCHAR]; // unknown initialization records

  // for map routine
extern long int map_version_from, map_version_to, map_always;

  // for post routines
extern long int post_found, post_node[4], post_node_length, npost_node;
extern double post_point[MDIM], post_point_dof[MUKNWN], 
  post_node_result[DATA_ITEM_SIZE];

  // for calcul routine
extern long int calcul_matrix, calcul_vector, calcul_scalar_indx,
  calcul_operat, calcul_mat_indx, calcul_vec_indx;

  // for geometry routine
extern long int geometry_ent[2], *nodes_in_geometry;

  // c routines
extern "C" 
  int umat_(double *stress, double *statev, double *ddsdde, 
    double *sse, double *spd, double *scd, double *rpl, double *ddsddt,
    double *drplde, double *drpldt, double *stran, double *dstran, 
    double *time, double *dtime, double *temp, double *dtemp, double *predef, 
    double *dpred, char *cmname, long int *ndi, 
    long int *nshr, long int *ntens, long int *nstatv, 
    double *props, long int *nprops, double *coords, double *drot, 
    double *pnewdt, double *celent, double *dfgrd0, double *dfgrd1, 
    long int *noel, long int *npt, long int *layer, long int *kspt, 
    long int *kstep, long int *kinc, short cmname_len);
extern "C" 
  int dsbev_(char *jobz, char *uplo, integer *n, integer *kd, 
    doublereal *ab, integer *ldab, doublereal *w, doublereal *z, integer *
    ldz, doublereal *work, integer *info);
extern "C" 
  int dsbgv_(char *jobz, char *uplo, integer *n, integer *ka, 
    integer *kb, doublereal *ab, integer *ldab, doublereal *bb, integer *
    ldbb, doublereal *w, doublereal *z, integer *ldz, doublereal *work, 
    integer *info);
extern "C" 
  int mdgbsv_(integer *n, integer *kl, integer *ku, integer *nrhs, 
    doublereal *ab, integer *ldab, integer *ipiv, doublereal *b, 
    integer *ldb, integer *info);

  // routines
void      adjust_geom( void );
void      area( long int name, long int nnol, long int nodes[],
            double coord[], double new_dof[], double element_lhside[], 
            double element_matrix[], double element_rhside[],
            double element_rhside_internal[], double element_rhside_static[] );
void      area_element_group( long int version );
void      area_node_boundary( void );
void      array_add( double a[], double b[], double c[], long int n );
double    array_distance( double a[], double b[], double work[], long int n );
double    array_inproduct( double a[], double b[], long int n );
long int  array_member( long int i_list[], long int i, long int n, long int &indx );
void      array_move( long int from[], long int to[], long int n );
void      array_move( double from[], double to[], long int n );
void      array_multiply( double a[], double b[], double c, long int n );
long int  array_normalize( double a[], long int n );
long int  array_null( double dval[], long int n );
void      array_outproduct( double a[], double b[], double c[] );
void      array_set( long int i[], long int ival, long int n );
void      array_set( double d[], double dval, long int n );
double    array_size( double a[], long int n );
void      array_subtract( double a[], double b[], double c[], long int n );
void      bounda( void );
void      bounda_time_file_apply( long int iboun, double total_time,
            double bounda_time[], long int &ninc );
void      calculate( void );
void      calculate_operat( double unknown_values[], 
            double result[], long int &length_result );
long int  check( long int idat, long int task );
long int  check_ndim( long int lower, long int higher, long int task );
long int  check_unknown( char str[], long int initialization_needs_to_exist, 
            long int task );
long int  check_unknown_minimum( char str[], long int min, long int task );
long int  check_unknowns_are_specified( long int task );
long int  check_new_node( long int ordered_nodes[], long int new_max_node,
            double coord_new[], long int task );
void      step_close( long int ipar, long int npar, long int ipar_i,
            long int ipar_n );
void      step_start( void );
void      condif( long int element, long int gr, long int nnol, double h[], 
            double volume, double new_unknowns[], double element_lhside[],
            double element_matrix[], double element_rhside[], 
            double element_rhside_internal[],
            double element_rhside_static[], double element_residue[] );
void      C_matrix( double young, double poisson, double compressibility,
            double transverse_isotropy[], double C[MDIM][MDIM][MDIM][MDIM], 
            long int task[] );
void      create_element( long int old_element, long int new_element,
            long int el[], long int length_el,
            long int version_from, long int version_to );
void      create_node( long int old_nodes[], long int nnod, 
            long int tmp_node_number, double tmp_node[], double tmp_node_dof[], 
            double tmp_node_start_refined[], double tmp_node_dof_start_refined[],
            long int version_from, long int version_to );
void      damage( long int gr, double new_epe[], double new_sig[], 
            double old_damage, double &new_damage );
void      damage_mazars( double materi_damage_mazars[], double new_epe[], double new_sig[], 
            double old_damage, double &new_damage );
void      data( void );
long int  db( long int idat, long int index, long int *ival,
            double *dval, long int &length, long int version,
            long int task );
long int  db_active_index( long int idat, long int index, long int version );
void      db_allocate( long int idat, long int index, long int version,
            long int task );
void      db_allocate_class( long int cl, long int index, long int version );
void      db_close( );
void      db_copy( long int idat, long int jdat, long int version );
long int  db_data_length( long int idat );
void      db_data_length_put( long int idat, long int length );
long int  db_data_class( long int idat );
double   *db_dbl( long int idat, long int version );
double   *db_dbl( long int idat, long int index, long int version );
void      db_delete( long int idat, long int version );
void      db_delete_index( long int idat, long int index, long int version );
void      db_error( long int idat, long int index );
long int  db_external( long int idat );
long int  db_fixed_length( long int idat );
void      db_highest_index( long int idat, long int &max, long int version );
void      db_initialize( long int dof_type[], long int dof_label[] );
long int *db_int( long int idat, long int version );
long int *db_int( long int idat, long int index, long int version );
long int  db_len( long int idat, long int index, long int version );
long int  db_max_index( long int idat, long int &max, long int version,
            long int task );
char     *db_name( long int idat );
long int  db_no_index( long int idat );
long int  db_number( char name[] );
long int  db_print_only( long int idat );
long int  db_version( long int idat, long int version );
void      db_version_copy( long int version_from, long int version_to );
void      db_version_delete( long int version );
void      db_set_int( long int jdat, long int version );
void      db_set_dbl( long int jdat, long int version );
long int  db_type( long int idat );
void      delete_element( long int element, long int version );
void      delete_geom( long int task );
void      delete_node( long int inod, long int version );
void      dof_tyings( void );
void      elem( long int element, long int ithread );
void      element_loop( void );
long int  element_residue_norm_set( long int icontrol,
            long int control_refine_locally_unknown,
            long int element, double &element_residue_norm, long int version );
void      element_volume_set( long int nodes[], long int version, 
            double &element_volume );
void      equal( void );
void      error( long int task );
void      exit_tn( void );
void      failure( void );
long int  filter( long int idat, long int index, long int number, long int task );
void      force_element_volume_set( long int element, long int nnol, long int nodes[],
            double coord[], double force_element_volume[] );
long int  force_time( double time_table[], long int length, double &load );
void      general( long int element, long int name, long int nnol, long int gr, 
            long int type, long int nodes[], double old_dof[], double new_dof[],
            double new_unknowns[], double grad_new_unknowns[], double h[], 
            double d[], double volume,
            double element_rhside[], double element_rhside_internal[],
            double element_rhside_static[], double element_residue[], 
            double element_lhside[], double element_matrix[],
            double cons_var_vel[], double grad_cons_var_flow[] );
void        geometry( long int inod, double co[], long int geometry_entity[],
            long int &found, double &factor, double normal[],
            double &penetration, double projection[],
            long int node_type, long int projection_type, long int version );
long int  get_group_data( long int idat, long int group, double new_unknowns[],
            double values[], long int &nvalue, long int task );
char     *get_new_char( long int n );
double   *get_new_dbl( long int n );
long int *get_new_int( long int n );
void      groundflow( long int element, long int group, long int nnol,
            double h[], double d[], double volume, double old_unknowns[], 
            double new_unknowns[], double grad_new_unknowns[],
            double element_matrix[], double element_rhside[],
            double element_rhside_internal[], double element_rhside_static[], 
            double element_residue[] );
void      hyperelasticity( long int element, long int gr, double old_unknowns[],
            double new_unknowns[], double old_epe[], double new_epe[], 
            double new_sig[] );
void      hyper_law( long int hyper_type, double hyper_data[], double C[], 
            double &W );
void      initialize( void );
void      initialize_bounda_elem( long int control_solver );
void      input( char nam[] );
void      input_convert_to_lower_case( char str[] );
void      input_read_string( long int echo, char str[] );
void      input_skip_comment( char str[] );
long int  integration_gauss( long int niso, double iso[], double weight_iso[]);
long int  integration_lobatto( long int niso, double iso[], 
            double weight_iso[] );
void      interpolate_geometry( long int geometry_entity[],
            long int node_numbers[], long int n,
            double test_coord[], double tmp_node[],
            double test_coord_start_refined[], 
            double tmp_node_start_refined[], 
            long int project_type, long int version );
void      interpolation_polynomial( double iso, long int npol, double h_pol[],
            double p_pol[] );
long int  intersect_line_with_line( double line_a0[], double line_a1[], 
            double line_b0[], double line_b1[], double &iso_line_a,
            double &iso_line_b );
long int  intersect_line_with_point( double line0[], double line1[], 
            double point[], double &iso_line );
long int  intersect_line_with_triangle( double line0[], double line1[], 
            double triangle0[], double triangle1[], double triangle2[], 
            double &iso_line, double iso_triangle[] );
void      inverse_calculation( long int ipar, long int npar, long int ipar_i,
            long int ipar_n, long int max_time, long int task );
void      locate( void );
char     *long_to_a( long int i, char str[] );
void      macro( void );
void      map_element( long int element );
void      map_node( long int inod );
void      materi( long int element, long int group, long int nnol, 
            long int npoint, double coord_ip[],
            double old_coord[], double h[], double new_d[], 
            double new_b[], double new_bnl[], double volume,
            double old_unknowns[], double new_unknowns[],
            double old_grad_old_unknowns[], double old_grad_new_unknowns[], 
            double new_grad_new_unknowns[], double element_lhside[], 
            double element_matrix[], double element_matrix_stress_stiffness[],
            double element_rhside[], double element_rhside_internal[], 
            double element_rhside_static[], double element_residue[], 
            double tendon_element_rhside[] );
void      matrix_ab( double *a, double *b, double *c, long int n, long int m,
            long int k );
void      matrix_abat( double a[], double b[], double c[], double work[],
            long int n );
void      matrix_abt( double *a, double *b, double *c, long int n, long int m,
            long int k );
void      matrix_atb( double *a, double *b, double *c, long int n, long int m,
            long int k );
void      matrix_atba( double a[], double b[], double c[], 
            double work[], long int n, long int m );
void      matrix_a4b( double a[MDIM][MDIM][MDIM][MDIM], double b[], 
            double c[] );
double    matrix_determinant( double a[], long int n );
void      matrix_eigenvalues( double a[], double eigenvalues[] );
void      matrix_invariants( double matrix[], double inv[] );
long int  matrix_inverse( double mat[], double inv_mat[], double &det, 
            long int n );
void      matrix_jacobi( double *a, long int n, double d[], 
            double *v, long int *nrot);
void      matrix_insert( double *a, long int n, long int m,
             double *b, long int k, long int l, long int p );
long int  membrane_apply( long int element, long int gr, double memmat[3][3], 
            double inc_ept[], double inc_epe[], double new_sig[] );
void      merge( void );
void      mesh_add( long int version_from, long int version_to );
void      mesh_has_changed( long int version );
void      new_mesh( void );
void      new_mesh_version( long int version, double delta );
void      nod_nod( long int version );
void      parallel_calcul_node( void );
void      parallel_contact( void );
void      parallel_element_loop( void );
void      parallel_geometry( void );
void      parallel_map_element( void );
void      parallel_map_node( void );
void      parallel_new_dof_before( void );
void      parallel_new_dof_diagonal( void );
void      parallel_post_point( void );
void      parallel_post_node( void );
void      parallel_remesh( void );
void      parallel_solve_iterative_element( void );
void      parallel_sys_initialize( void );
void      parallel_sys_lock( void );
void      parallel_sys_next_of_loop( long int next_of_loop[], 
            long int max_loop, long int &nloop, long int &ithread );
void      parallel_sys_routine( void (*routine)(void) );
void      parallel_sys_unlock( void );
void      plasti_rule( long int element, long int group, double user_data[],
            double new_unknowns[], double new_grad_new_unknowns[],
            double old_hisv[], double new_hisv[], 
            long int task, long int &plasti_type, 
            double sig[], double &f, double dir[] );
long int  point_el( double point[], double coord[], double weight[],
            long int name, long int nnol );
void      pol( long int element, long int element_group,
            long int name, long int nnol, double old_coord[], 
            double new_coord[], long int &npoint, double h[], double old_d[], 
            double new_d[], double new_b[], double new_bnl[], double volume[] );
void      post( void );
void      post_node_rhside_fixed_free( void );
void      pri( char *s );
void      pri( char *s, char *st );
void      pri( char *s, long int i );
void      pri( char *s, double d );
void      pri( char *s, long int i[], long int n );
void      pri( char *s, long int i[], long int n, long int m );
void      pri( char *s, double d[], long int n );
void      pri( char *s, double d[], long int n, long int m );
void      print( long int task, long int version, long int idat );
void      print_cmd( void );
void      print_data_versus_data( long int ival[] );
void      print_gmv( long int icontrol, long int ival[] );
void      print_history( long int ival[], long int nval );
void      print_plotmtv( long int icontrol, long int ival[] );
void      print_matlab( void );
void      print_tecplot( long int ival[] );
void      print_vtk( long int icontrol );
long int  project_point_exactly_on_line( double coord[], double coord0[], 
            double coord1[], double weight[] );
long int  project_point_exactly_on_quad( double coord[], double coord0[], 
            double coord1[], double coord2[], double coord3[], double weight[] );
long int  project_point_exactly_on_triangle( double coord[], double coord0[], 
            double coord1[], double coord2[], double weight[] );
long int  project_point_on_line( double coord[], double coord0[], 
            double coord1[], double weight[] );
long int  project_point_on_triangle( double coord[], double coord0[], 
            double coord1[], double coord2[], double weight[] );
void      range_expand( long int ival[], long int integer_range[],
            long int &length, long int &range_length );
void      range_scan( long int ival[], long int &length );
void      range_testi( long int i );
void      refine_locally( void );
void      refine_globally( long int control_refine_globally[4], 
            long int length_control_refine_globally, 
            long int use_control_refine_globally_geometry, 
            long int control_refine_globally_geometry[2],
            long int project_type, long int version );
void      renumbering( long int version, long int lowest_element, long int lowest_node );
void      renumbering_check( long int idat );
long int  repeat( long int &start_control );
void      restart( void );
double    scalar_dabs( double a );
double    scalar_dmax( double a, double b );
double    scalar_dmin( double a, double b );
long int  scalar_iabs( long int i );
long int  scalar_imax( long int a, long int b );
double    scalar_sign( double a );
double    scalar_square( double a );
void      set_deften_etc( long int element, long int gr, long int nnol, 
            double h[], double old_coord[],
            double old_unknowns[], double new_unknowns[], 
            double old_grad_old_unknowns[], double old_grad_new_unknowns[], 
            double old_ept[], double inc_ept[],
            double old_rot[], double inc_rot[], double new_rot[] );
void      set_environment( void );
void      set_stress( long int element, long int gr, 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 old_epe[], double inc_epe[], double new_epp[], 
            double old_rho[], double new_rho[],
            double old_hisv[], double new_hisv[], 
            double old_damage, double &new_damage,
            double old_kappa, double &new_kappa,
            double ddsdde[] );
long int  set_swit( long int element, long int node, char routine[] );
void      sigmat_fill( double sigvec[], double sigmat[] );
void      slide( long int task );
void      solve( long int task );
void      solve_iterative( void );
void      solve_iterative_sys( double *Ad1, double *Ad2, double *p_tmp, double *residue );
void      solve_iterative_element( long int element, long int ithread );
void      sort( double val[], double vec[] );
void      split( long int version );
long int  stress_indx( long int idim, long int jdim );
void      stress_umat( long int element, long int gr,
            long int nuser_data, double user_data[], double coord_ip[],
            double old_hisv[], double new_hisv[], 
            double old_unknowns[], double new_unknowns[], 
            double old_epe[], double inc_epe[], 
            double rotated_old_sig[], double new_sig[],
            double ddsdde[] );
void      string_convert_to_lower_case( char str[] );
long int  string_isdouble( char str[] );
long int  string_isinteger( char str[] );
void      string_reverse( char str[] );
void      tendon_distribute();
void      tendons( long int element, long int gr, long int nnol, 
            long int npoint, double volume,
            double new_d[], double old_unknowns[], double new_unknowns[],
            double new_rot[], double inc_ept[], double tendon_element_rhside[],
            double ddsdde_tendon[] );
double    tetrahedron_volume( double c0[], double c1[], 
            double c2[], double c3[] );
void      top( void );
double    triangle_area( double c0[], double c1[], double c2[] );
void      tyings_setup( long int from_node, long int to_node,
            long int tyings_unknowns[] );
void      tyings_rhside_lhside( void );
void      tyings_node_dof( long int version );
void      user_plasti( long int task, double user_data[],
            double new_unknowns[], double old_hisv[],
            double new_hisv[], double sig[], double &f );
void      user_sigma( double user_data[], double new_unknowns[], 
            double inc_epe[], double new_epe[], 
            double old_hisv[], double new_hisv[], 
            double old_sig[], double new_sig[], 
            double Cuser[MDIM][MDIM][MDIM][MDIM] );
void      user_viscosity( double user_data[], double new_unknowns[], 
            double &visc );
void      visco_elasticity( long int element, long int group, 
            double new_unknowns[], double inc_epe[], double rotated_old_msig[],
            double new_sig[], double new_msig[], double memmat[MDIM][MDIM] );
void      viscous_stress( long int element, long int gr, double user_data[],
            double old_unknowns[], double new_unknowns[], 
            double old_grad_old_unknowns[], double new_grad_new_unknowns[],
            double new_sig[] );
void      volume_factor( long int element_group, double coord[], double &volfac );
void      wave( long int element, long int gr, long int nnol,
            double h[], double d[], double volume, double new_unknowns[], 
            double grad_new_unknowns[], double element_matrix[],
            double element_rhside[], double element_rhside_internal[],
            double element_rhside_static[], double element_residue[] );
