/*************************************************************
Filename:       read.c
Authors: 	Eija Achren, Lauri Glad, Pekka Haara, Tuija Rinne, Sarianne Mykra

Date:           16.6.1992

Description:


Modifications:

**************************************************************/

#include "fem.h"
#include "defin.h"

#include <stdio.h>
#include <stdlib.h>


extern int error_message(char *, char *,char *, int,STime *);
int find_step_inc(NodalData *);

/*************************************************************
Function: 	read_initial_data

Description: 	Reads the original nodal coordinates and the 
		topology of the model from a specified file.

Input: 		filename: file name
Output: 	*original: pointer to the structure which holds 
			the nodal coordinates & element topology

Return: 	OK, if reading succesfull
        	ERROR, if not 
--------------------------------------------------------------*/
int read_initial_data(filename, changes, original, inc_time)

char *filename;
AllData *changes;
Model *original;
STime *inc_time;

{
int temp; 

       ABAQUS_Close(); /* Lets start with a closed file */
       if(ABAQUS_Open(filename) < 0)
	 {
	 temp = error_message("File '%s' is not a proper ABAQUS Output file or\nelement and nodal data is not written yet. %s", filename, "\nDo you wish to set the autoupdate function on ?\n",-4,NULL);
	 if(temp != OK)
	   return ERROR;
	 }
	if (original->node != NULL)
	       free(original->node);
	if (original->elem != NULL)
	       free(original->elem);

	if (ABAQUS_Read_Model(original) < 0)
	  {
	       error_message("Can not read model topology data from the file '%s'.",filename,NULL,-2,NULL);
	       return ERROR;
	  }


	if (inc_time->inc != NULL)
	       free(inc_time->inc);
	if (inc_time->step != NULL)
	       free(inc_time->step);
	if (inc_time->time != NULL)
	       free(inc_time->time);

	if (ABAQUS_Time_Data(inc_time) < 0)
	  {
             
		temp =  error_message("Can not read time data from the file! '%s'.%s",filename, "\nDo you wish to set the autoupdate function on ?\n",-5,inc_time); 
		if(temp!=OK)
		  return ERROR;
	  }

	if (changes->stress.data != NULL)
	  {
	    ABAQUS_Free_NodalData(&changes->stress);
	    free(changes->stress.nid);
	  }
	if (changes->von_Mises.data != NULL)
	  {
	    ABAQUS_Free_NodalData(&changes->von_Mises);
	    free(changes->von_Mises.nid);
	  }
	if (changes->max_shear.data != NULL)
	  {
	    ABAQUS_Free_NodalData(&changes->max_shear);
	    free(changes->max_shear.nid);
	  }
	if (changes->temp.data != NULL)
	  {
	    ABAQUS_Free_NodalData(&changes->temp);
	    free(changes->temp.nid);
	  }
	if (changes->disp.data != NULL)
	  {
	    ABAQUS_Free_NodalData(&changes->disp);
	    free(changes->disp.nid);
	  }


	/* allocate memory for nodal data components		*/
	
 	if(ABAQUS_Alloc_NodalData(&(changes->stress),6) < 0) 
	    error_message("Memory allocation failed.",NULL,NULL,-3,NULL);
	 
	if(ABAQUS_Alloc_NodalData(&(changes->disp),3) < 0)
	    error_message("Memory allocation failed.",NULL,NULL,-3,NULL);

	if (ABAQUS_Alloc_NodalData(&(changes->temp),1) < 0) 
	    error_message("Memory allocation failed.",NULL,NULL,-3,NULL);

	if(ABAQUS_Alloc_NodalData(&(changes->von_Mises),1) < 0) 
	    error_message("Memory allocation failed.",NULL,NULL,-3,NULL);

	if(ABAQUS_Alloc_NodalData(&(changes->max_shear),1) < 0) 
	    error_message("Memory allocation failed.",NULL,NULL,-3,NULL);

	return(OK);
 
} /*read_initial_data*/


/*************************************************************
Function:	read_ABAQUS_data

Description:	reads the nodal data of a specified time increment

Input: 		

Output:		*changes: contains all the changes of nodal data 
			components on the current time increment

Global variables: 
		filename
		step_nr
		inc_nr
		shell_elem
		

Return: 	OK, if reading succesful
		ERROR, if not 
-------------------------------------------------------------*/

int read_ABAQUS_data(changes, last_step, last_inc)

AllData *changes;
int last_step, last_inc;

{	
  int shell_layer;
  int elem_type,i,j;
  
  /* set the parameters for the function call for reading the stresses */
  if (shell_elem == 0)
    {
      elem_type = STR_SOLID;
      shell_layer=0;
    } 
  else 
    {
      elem_type = STR_SHELL;
      if (shell_elem >= MAX_LAYER)
	shell_layer = STR_TOP;
      else shell_layer = shell_elem;
    }
	
    /* read stresses for solid elements or for a  specified layer of shell elements */
    if(changes->stress.data != NULL)
    {
	if (find_step_inc(&(changes->stress)) > 0)
	  {
		if (ABAQUS_Read_Stress(&(changes->stress),elem_type,STR_NORMAL,shell_layer) < 0 )
		  {
		    ABAQUS_Free_NodalData(&changes->stress);
		    changes->stress.data = NULL;
		  }
	      }
	 else
	   {

                 ABAQUS_Free_NodalData(&changes->stress);
		 changes->stress.data = NULL;
		 ABAQUS_Free_NodalData(&changes->von_Mises);
		 changes->von_Mises.data = NULL;
		 ABAQUS_Free_NodalData(&changes->max_shear);
		 changes->max_shear.data = NULL;
		 ABAQUS_Free_NodalData(&changes->disp);
		 changes->disp.data = NULL;
		 ABAQUS_Free_NodalData(&changes->temp);
		 changes->temp.data = NULL;
	         error_message("The file does not contain data for selected step or increment.",NULL,NULL,-2,NULL);
		 return ERROR;
	   }
      }
      /* read von Mises stresses */
      if(changes->von_Mises.data != NULL)
      {
        find_step_inc(&(changes->von_Mises));
        if (ABAQUS_Read_Stress(&(changes->von_Mises),elem_type,STR_VON_MISES,shell_layer) < 0) 
	  {
	    ABAQUS_Free_NodalData(&changes->von_Mises);
	    changes->von_Mises.data = NULL;
	  }
      }

      /* read max shear stresses */
      if(changes->max_shear.data != NULL)
      {
	find_step_inc(&(changes->max_shear));
	if (ABAQUS_Read_Stress(&(changes->max_shear),elem_type,STR_MAX_SHEAR,shell_layer) < 0 )
	 {
	   
	   ABAQUS_Free_NodalData(&changes->max_shear);
	   changes->max_shear.data = NULL;
	 }
	
      }

	/* if step or inc widgets have been changed, all the nodal data must be read */
 
	if (step_nr != last_step || inc_nr != last_inc)
	{
		/* read displacements */
	        if(changes->disp.data != NULL)
		  {
		    find_step_inc(&(changes->disp));
		    if(ABAQUS_Read_Disp(&(changes->disp)) < 0)
		      {
			ABAQUS_Free_NodalData(&changes->disp);
			changes->disp.data = NULL;
		      }
		  }
               
     		/* read temperatures */
		if(changes->temp.data != NULL)
		  {
		    find_step_inc(&(changes->temp));
		    if (ABAQUS_Read_Temp(&(changes->temp)) < 0)
		       {
			  ABAQUS_Free_NodalData(&changes->temp);		        
			  changes->temp.data = NULL;
		        }
		   }
      }
return(OK);
}/*read_ABAQUS_data*/

/*************************************************************
Function:	find_step_inc

Description:	Locates the wanted step and increment from ABAQUS output file.
		Assigns the values to NodalData structure passed as parameter.
Input: 		

Output:		*data: structure contains the values for current step, inc and time.

Global variables: 
		step_nr
		inc_nr		

Return: 	OK, if reading succesful
		ERROR, if not 
-------------------------------------------------------------*/

int find_step_inc(data)
NodalData *data;
{
	NodalData ndp;
	int i;

	/* find the right step and increment from file		*/
	ABAQUS_Rewind();
	do
        {
	        i=(ABAQUS_Next_Time_Step(&ndp));
		  
	} while( i > 0 && (ndp.step < step_nr || (ndp.step==step_nr && ndp.inc < inc_nr)));

	if (i < 0){
	        return(ERROR);
	      }
	else
	{
	       data->step = ndp.step;
	       data->inc = ndp.inc;
	       data->time = ndp.time;
	       return(OK);
	}
}



       
