示例#1
0
const Matrix&
PFEMElement2D::getDamp()
{

    // resize K
    K.resize(ndf, ndf);
    K.Zero();

    // K, G, Gt
    for (int a=0; a<3; a++) {
	for (int b=0; b<3; b++) {

	    // K
	    if (lumped == false) {
		K(vxdof[a], vxdof[b]) += Km(2*a,2*b);
		K(vxdof[a], vydof[b]) += Km(2*a,2*b+1);
		K(vydof[a], vxdof[b]) += Km(2*a+1,2*b);
		K(vydof[a], vydof[b]) += Km(2*a+1,2*b+1);
	    }

	    // -G
	    K(vxdof[a], pdof[b]) = -Gx[a];
	    K(vydof[a], pdof[b]) = -Gy[a];

	    // Gt
	    K(pdof[b], vxdof[a]) = Gx[a];
	    K(pdof[b], vydof[a]) = Gy[a];

	    // S
	    K(pdof[a], pdof[b]) = S(a,b);
	}

    }


    return K;
}
int main(int argc, char **argv)
{
  int world_size;
  float dvalue = 0.0;
  int flag_script;
  int recvd_proc_rank;
  int send_to_rank;
  int procs_completed = 1;
  int my_rank;
  int loop_var;
  int processors;
  int n_steps = (int)time_max / dt;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int name_length;
  int current_trial;
  int base_rank = 1;
  int loop_ends = 0;
  char *file_path = (char*)malloc(100*sizeof(char));
  char *base_path = (char*)malloc(100*sizeof(char));
  char *coupling_path = (char*)malloc(8*sizeof(char));
  char *trial_path = (char*)malloc(8*sizeof(char));
  double _FinalISI[10][100];
  // _FinalISI = alloc_2d_float(10,100);
  int _no_spikes[10][100];
  // _no_spikes = alloc_2d_int(10,100);
  double _connections[10][100];
  // _connections = alloc_2d_double(10,100);
  double _tot_degree[10][12];
  // _tot_degree = alloc_2d_double(10,12);
  int _count_degree[10][12];
  // _count_degree = alloc_2d_int(10,12);
  double *_firing_coherence = (double *)malloc(10*sizeof(double));
  int *recvd_rank = (int *)malloc(10*sizeof(int));
  int rec_proc_rank;

  int i, j, l;            //Looping variables. Not using k because it is already used

  MPI_Init(&argc, &argv);
  float dmin = strtof(argv[1], NULL);
  float dmax = strtof(argv[2], NULL);
  float dstep = strtof(argv[3], NULL);
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Get_processor_name(processor_name, &name_length);

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////

  // the scheduler process is mapped to the the first core of the first socket

  if (my_rank == 0)
  {
    // printf("value of N is %d", N);
    srand(time(NULL) + my_rank*world_size);
    flag_script = system("nproc > processors.txt ");
    if (flag_script)
    {
      fprintf(stderr, "Failed to launch script nproc > processors.txt\n");
      return 1;
    }

    FILE *no_processors = fopen("processors.txt", "r");
    fscanf(no_processors, "%d", &processors);
    fclose(no_processors);

    flag_script = system("rm processors.txt");
    if (flag_script)
    {
      fprintf(stderr, "Failed to launch script rm processors.txt\n");
      return 1;
    }

    ///////////////////////////////check the condition////////////////////////////////////////////////////////////

    for(loop_var = 0; loop_var < (3*processors)/11; loop_var++)
    {
      //using a synchronous send to different cores which correspond to coupling strength values
      // in case of processors > processes, keep a check condition based on dmax
      if (base_rank < world_size)
      {
        dvalue = dmin + loop_var*dstep;
        MPI_Send(&dvalue, 1, MPI_FLOAT, base_rank, 0, MPI_COMM_WORLD);
        base_rank+=11;
        // procs_completed+=10;
      }
    }

    while (1)
    {
      // Receive the rank of the process completed

      MPI_Recv(&recvd_proc_rank,1,MPI_INT,MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      // printf("RECEIVED PROCESS %d\n", recvd_proc_rank);
      if ((recvd_proc_rank-1)%11 == 0)    // Safeguard to ensure that only the coupling process sends back data
      {
        procs_completed+=11; // or 11? Increment the number of completed
        // printf("procs completed are %d\n",procs_completed);
        if (procs_completed == world_size)
        {
            break;
        }

        if (base_rank < world_size)  // Send the computed process to the free set of cores
        {
          // instead of changing the rankfile, find the process(es) which yields the same mapping to the cores
          // as the coupling_strength process which completed, and launch it
          dvalue = dmin + dstep*(base_rank/11);
          // printf("Sending the dvalue %f with dmax as %f to %d\n", dvalue, dmax, base_rank);
          MPI_Send(&dvalue, 1, MPI_FLOAT, base_rank, 0, MPI_COMM_WORLD);
          // printf("SENT PROCESS %d\n", recvd_proc_rank);
          base_rank+=11;
        }
      }
      if ((recvd_proc_rank-1)%11 != 0 )
      {
        printf("ERROR ENCOUNTERED\n");
      }
    }
  }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

    // First thread section, associate each file pointer with a thread for initialisation
    // Destroy threads and dynamic memory after allocation

    // long thread = 0;
    // int thread_count = 4;
    // pthread_t *thread_handles;
    // pthread_attr_t attr;
    //
    // thread_handles = malloc(thread_count*sizeof(pthread_t));
    // pthread_attr_init(&attr);
    //
    // pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    //
    // for (thread = 0; thread < thread_count; thread++)
    // {
    //   pthread_create(&thread_handles[thread], &attr, declare_init_files, (void*) thread);
    // }
    //
    // for(thread = 0; thread < thread_count; thread++)
    // {
    //   pthread_join(thread_handles[thread], NULL);
    // }
    //
    // free(thread_handles);

    //End of first thread section


  ///////////////////////////////////////////////////////////////////////////////////////////////////////////

  // TO DO
  // Compute a stringbuilder for the file paths
  // Recieve all the variables and do the computations
  // Write the values to the files
  // Send the final computations to the coupling process

  if ((my_rank-1)%11 == 0)
  {
    // printf("Rank is %d", my_rank);
    srand(time(NULL) + my_rank*world_size);
    // Recieve the coupling strength value from the scheduler process;

    MPI_Recv(&dvalue, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

    snprintf(coupling_path, 8, "%f", dvalue);
    getcwd(file_path, 100);
    strcat(file_path, "/");
    strcat(file_path,coupling_path);
    strcat(file_path, "/");
    strcpy(base_path, file_path);

    // This file stores the Firing Coherence values for various coupling strengths (D)

    strcat(file_path, "FiringCoherenceVaryingDs(100,8)(0.9;0.6).txt");
    firingcoherenceid = fopen(file_path, "w");

    // This file stores the Firing Correlation values as a function of degree of separation

    strcpy(file_path, base_path);
    strcat(file_path, "FCDegreeVaryingD(100,8)(0.9;0.6).txt");
    fcdegreeid = fopen(file_path, "w");

    // This file stores the ISIs of induvidual neurons in the network

    strcpy(file_path, base_path);
    strcat(file_path, "ISI_no_connections(100,8)(0.9;0.6).txt");
    fisiid = fopen(file_path, "w");

    // This file stores the mean ISI of all the neurons in the network

    strcpy(file_path, base_path);
    strcat(file_path, "MeanISI(100,8)(0.9;0.6).txt");
    fmeanisiid = fopen(file_path, "w");

    // printf("D = %f\n", dvalue);

    /*We are calculating the firing correlation as a function of degree in the network
     * We are averaging our results over a number of variations in the network to reduce
     * the effects of noise on the validity of our results.
     * tot_degree is a variable which stores the firing correlation value over a particular degree of separation
     * Over 'n' trials, we add up the values of firing correlation for one particular degree of separation in this
     * and divide by the number of trials in which neurons are separated by those many number of hops
     * count_degree stores the number of trials in which there exists a particular degree of separation
     */

    for (i = 0; i < N; i++) // i ---> number of neurons
    {
      no_spikes[i] = 0;
      FinalISI[i] = 0.0;
      connections[i] = 0;
    }

    for (i = 0; i < 12; i++)    // i ---> degree of separation
    {
      tot_degree[i] = 0;
      count_degree[i] = 0;
    }

    // To send -
    // Trial number to each core
    // FinalISI over all the trials
    // no_spikes over all the trials
    // connections over all the trials
    // count_degree over all the trials
    // tot_degree over all the trials
    // firing_coherence over all the trials

    // trial / current_trial
    for (send_to_rank = my_rank + 1, trial = 0; send_to_rank < my_rank + 11; send_to_rank++, trial++)
    {
      MPI_Send(&(FinalISI[0]), 100, MPI_DOUBLE, send_to_rank, 0, MPI_COMM_WORLD);
      MPI_Send(&(no_spikes[0]), 100, MPI_INT, send_to_rank, 1, MPI_COMM_WORLD);
      MPI_Send(&(connections[0]), 100, MPI_DOUBLE, send_to_rank, 2, MPI_COMM_WORLD);
      MPI_Send(&tot_degree[0], 12, MPI_DOUBLE, send_to_rank, 3, MPI_COMM_WORLD);
      MPI_Send(&count_degree[0], 12, MPI_INT, send_to_rank, 4, MPI_COMM_WORLD);
      MPI_Send(&firing_coherence, 1, MPI_DOUBLE, send_to_rank, 5, MPI_COMM_WORLD);
      MPI_Send(&my_rank, 1, MPI_INT, send_to_rank, 6, MPI_COMM_WORLD);
      MPI_Send(&dvalue, 1, MPI_FLOAT, send_to_rank, 7, MPI_COMM_WORLD);
      MPI_Send(&trial, 1, MPI_INT, send_to_rank, 8, MPI_COMM_WORLD);
    }

    // To recieve -
    // FinalISI over all the trials
    // no_spikes over all the trials
    // connections over all the trials
    // count_degree over all the trials
    // tot_degree over all the trials
    // firing_coherence over all the trials

    for (i = 0; i < N; i++) // i ---> number of neurons
    {
      no_spikes[i] = 0;
      FinalISI[i] = 0.0;
      connections[i] = 0;
    }

    for (i = 0; i < 12; i++)    // i ---> degree of separation
    {
      tot_degree[i] = 0;
      count_degree[i] = 0;
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 100; i++)
      {
        _FinalISI[loop_var][i] = 0;
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 100; i++)
      {
        _no_spikes[loop_var][i] = 0;
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 100; i++)
      {
        _connections[loop_var][i] = 0;
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 12; i++)
      {
        _tot_degree[loop_var][i] = 0;
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 12; i++)
      {
        _count_degree[loop_var][i] = 0;
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      _firing_coherence[loop_var] = 0;
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      recvd_rank[loop_var] = 0;
    }

    for (send_to_rank = my_rank + 1, loop_var = 0; send_to_rank < my_rank + 11; send_to_rank++, loop_var++)
    {
      // MPI_Send(&(FinalISI[0]), 100, MPI_DOUBLE, recvd_proc_rank, 0, MPI_COMM_WORLD);
      // MPI_Send(&(no_spikes[0]), 100, MPI_INT, recvd_proc_rank, 1, MPI_COMM_WORLD);
      // MPI_Send(&(connections[0]), 100, MPI_DOUBLE, recvd_proc_rank, 2, MPI_COMM_WORLD);
      // MPI_Send(&tot_degree[0], 12, MPI_DOUBLE, recvd_proc_rank, 3, MPI_COMM_WORLD);
      // MPI_Send(&count_degree[0], 12, MPI_INT, recvd_proc_rank, 4, MPI_COMM_WORLD);
      // MPI_Send(&firing_coherence, 1, MPI_DOUBLE, recvd_proc_rank, 5, MPI_COMM_WORLD);
      // MPI_Send(&recvd_rank, 1, MPI_INT, recvd_proc_rank, 6, MPI_COMM_WORLD);

      MPI_Recv(&(_FinalISI[loop_var][0]), 100, MPI_DOUBLE, send_to_rank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&(_no_spikes[loop_var][0]), 100, MPI_INT, send_to_rank, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&(_connections[loop_var][0]), 100, MPI_DOUBLE, send_to_rank, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&_tot_degree[loop_var][0], 12, MPI_DOUBLE, send_to_rank, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&_count_degree[loop_var][0], 12, MPI_INT, send_to_rank, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&_firing_coherence[loop_var], 1, MPI_DOUBLE, send_to_rank, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      MPI_Recv(&recvd_rank[loop_var], 1, MPI_INT, send_to_rank, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      if (isnan(_firing_coherence[loop_var]) == 0)
        firing_coherence += _firing_coherence[loop_var];
    }

    // for (loop_var = 0; loop_var < 10; loop_var++)
    // {
    //   for (i = 0; i < 100; i++)
    //   {
    //     printf("%f ",_connections[loop_var][i]);
    //   }
    //   printf("\n");
    // }

    firing_coherence/=10.0;

    // printf("Firing Coherence = %f\n", firing_coherence);
    fprintf(firingcoherenceid, "%f\t%f\n", dvalue, firing_coherence);

    fprintf(fcdegreeid, "#D = %f\n", dvalue);
    fprintf(fcdegreeid, "\n");

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 12; i++)
      {
        if (isnan(_tot_degree[loop_var][i]) == 0)
          tot_degree[i]+=_tot_degree[loop_var][i];
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < 12; i++)
      {
        if (isnan(_count_degree[loop_var][i]) == 0)
          count_degree[i]+=_count_degree[loop_var][i];
      }
    }

    for (i = 0; i < 12; i++)
    {
      tot_degree[i] = tot_degree[i] / count_degree[i];
      //fprintf(degreefcid, "%d\t%f\n",i+1,tot_degree[i]);
      fprintf(fcdegreeid, "%d\t%f\n", i + 1, tot_degree[i]);
    }

    fprintf(fcdegreeid, "\n");
    fprintf(fisiid, "#D = %f\n", dvalue);
    double mean = 0.0;
    double mean1 = 0.0;
    double stddev = 0.0;

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < N; i++)
      {
        if (isnan(_FinalISI[loop_var][i]) == 0)
          FinalISI[i]+=_FinalISI[loop_var][i];
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < N; i++)
      {
        if (isnan(_connections[loop_var][i]) == 0)
          connections[i]+=_connections[loop_var][i];
      }
    }

    for (loop_var = 0; loop_var < 10; loop_var++)
    {
      for (i = 0; i < N; i++)
      {
        if (isnan(_no_spikes[loop_var][i]) == 0)
          no_spikes[i]+=_no_spikes[loop_var][i];
      }
    }

    for (i = 0; i < N; i++)
    {
      FinalISI[i] = FinalISI[i] / 10.0;
      mean = mean + FinalISI[i];
      mean1 = mean1 + (FinalISI[i] * FinalISI[i]);
      //connections[i] = connections[i]/2.0;
      // FinalISI, connections averaged over all trials.
      fprintf(fisiid, "%d\t %f\t %d\t %f\n", i + 1, connections[i], no_spikes[i], FinalISI[i]);
    }

    fprintf(fisiid, "\n");
    mean = mean / N;
    mean1 = mean1 / N;
    stddev = sqrt(mean1 - (mean * mean));
    fprintf(fmeanisiid, "#D = %f\n", dvalue);
    fprintf(fmeanisiid, "Mean: %f\n", mean);
    fprintf(fmeanisiid, "Standard Deviation: %f\n", stddev);
    fprintf(fmeanisiid, "\n");
    //fclose(degreefcid);

    fclose(fcdegreeid);
    fclose(firingcoherenceid);
    fclose(fisiid);
    fclose(fmeanisiid);

    // Notify the scheduler that the process has completed

    MPI_Send(&my_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);

  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////////

  // TO DO
  // Compute a stringbuilder for the file paths
  // Recieve all the variables and do the computations
  // Write the values to the files
  // Send the final computations to the coupling process
  if ((my_rank-1)%11 != 0 && my_rank!=0)
  {

    srand(time(NULL) + my_rank*world_size);

    // add safeguards from the recieved process

    // MPI_Send(&(FinalISI[0]), 100, MPI_DOUBLE, send_to_rank, 0, MPI_COMM_WORLD);
    // MPI_Send(&(no_spikes[0]), 100, MPI_INT, send_to_rank, 1, MPI_COMM_WORLD);
    // MPI_Send(&(connections[0]), 100, MPI_DOUBLE, send_to_rank, 2, MPI_COMM_WORLD);
    // MPI_Send(&tot_degree[0], 12, MPI_DOUBLE, send_to_rank, 3, MPI_COMM_WORLD);
    // MPI_Send(&count_degree[0], 12, MPI_INT, send_to_rank, 4, MPI_COMM_WORLD);
    // MPI_Send(&firing_coherence, 1, MPI_DOUBLE, send_to_rank, 5, MPI_COMM_WORLD);
    // MPI_Send(&my_rank, 1, MPI_INT, send_to_rank, 6, MPI_COMM_WORLD);
    // MPI_Send(&dvalue, 1, MPI_FLOAT, send_to_rank, 7, MPI_COMM_WORLD);
    // MPI_Send(&trial, 1, MPI_INT, send_to_rank, 8, MPI_COMM_WORLD);

    MPI_Recv(&(FinalISI[0]), 100, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&(no_spikes[0]), 100, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&(connections[0]), 100, MPI_DOUBLE, MPI_ANY_SOURCE, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&tot_degree[0], 12, MPI_DOUBLE, MPI_ANY_SOURCE, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&count_degree[0], 12, MPI_INT, MPI_ANY_SOURCE, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&firing_coherence, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&rec_proc_rank, 1, MPI_INT, MPI_ANY_SOURCE, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&dvalue, 1, MPI_FLOAT, MPI_ANY_SOURCE, 7, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&current_trial, 1, MPI_INT, MPI_ANY_SOURCE, 8, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    // printf("Rank is %d and trial number is %d and dvalue is %f\n", my_rank, current_trial + 1, dvalue);

    getcwd(file_path, 100);
    snprintf(coupling_path, 8, "%f", dvalue);
    strcat(file_path, "/");
    strcat(file_path,coupling_path);
    strcat(file_path, "/");
    sprintf(trial_path, "%d", current_trial);
    strcat(file_path, trial_path);
    strcat(file_path, "/");

    strcpy(base_path, file_path);

    strcat(file_path, "V_vs_T.txt");
    fV_vs_t_id = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "Spiketime.txt");
    fspiketimeid = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "Y.txt");
    yid = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "VT.txt");
    fVTid = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "RewiredMatrix.txt");
    fAdjacencymatrixId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "Randomnumbers.txt");
    frandomnumberId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "NoOfConnections.txt");
    fNoConnectionsId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "m_noise.txt");
    fm_noiseId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "mvalues.txt");
    fmvalueId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "hvalues.txt");
    fhvalueId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "nvalues.txt");
    fnvalueId = fopen(file_path, "w");

    strcpy(file_path, base_path);
    strcat(file_path, "output.txt");
    ftrial_output = fopen(file_path, "w");

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

    // Second thread section, associate each file pointer with a thread for initialisation

    // These files are used for computing values of ISI, firing coeffiecients etc. for each trial
    // Files included are as follows -
    // fV_vs_t_id => V_vs_T.txt
    // fspiketimeid => Spiketime.txt
    // yid => Y.txt
    // fVTid => VT.txt
    // fAdjacencymatrixId => RewiredMatrix.txt
    // frandomnumberId => Randomnumbers.txt
    // fNoConnectionsId => NoOfConnections.txt
    // fm_noiseId => m_noise.txt
    // fmvalueId => mvalues.txt
    // fhvalueId => hvalues.txt
    // fnvalueId => nvalues.txt

    // Destroy threads and dynamic memory after allocation

    // thread = 0;
    // thread_count = 11;
    // pthread_t *thread_handles;
    // thread_handles = malloc(thread_count*sizeof(pthread_t));
    //
    // for (thread = 0; thread < thread_count; thread++)
    // {
    //   pthread_create(&thread_handles[thread], &attr, declare_trial_files, (void*) thread);
    // }

    // associate each block of initialisation with a seperate thread

    fprintf(ftrial_output, "p = %f\n", probability);

    int Done = 0;       //Flag

    //Initializing degree array
    for (i = 0; i < 20; i++)
    {
        degree[i] = 0;
    }

    //Initializing Edgematrix
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            edgematrix[i][j] = 0;
            edgematrix1[i][j] = 0;
        }
    }

    Nna = rhona * S;
    Nk = rhok * S;

    //Initializing V[j] Array

    //Constructing a ring lattice with k/2 connections on either side of each node

    for (i = 0; i < N; i++)
    {
        for (j = 1; j <= mean_degree/ 2; j++)
        {
            if ((i + j) >= N)
            {
                edgematrix[i][abs(N - (i + j))] = 1;
                edgematrix[i][abs(i - j)] = 1;
                edgematrix[abs(N - (i + j))][i] = 1;    //Since for an undirectional graph, edgematrix[i][j] = edgematrix[j][i]
                edgematrix[abs(i - j)][i] = 1;
            }
            else if ((i - j) < 0)
            {
                edgematrix[i][abs(N + (i - j))] = 1;
                edgematrix[i][abs(i + j)] = 1;
                edgematrix[abs(N + (i - j))][i] = 1;    //Since for an undirectional graph, edgematrix[i][j] = edgematrix[j][i]
                edgematrix[abs(i + j)][i] = 1;
            }
            else
            {
                edgematrix[i][abs(i + j)] = 1;
                edgematrix[i][abs(i - j)] = 1;
                edgematrix[abs(i + j)][i] = 1;          //Since for an undirectional graph, edgematrix[i][j] = edgematrix[j][i]
                edgematrix[abs(i - j)][i] = 1;
            }
        }
    }

    // for(thread = 0; thread < thread_count; thread++)
    // {
    //   pthread_join(thread_handles[thread], NULL);
    // }
    //
    // free(thread_handles);

    //End of second thread section

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////


    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            fprintf(fAdjacencymatrixId, "%f   ", edgematrix[i][j]);
            edgematrix1[i][j] = edgematrix[i][j];
        }
        fprintf(fAdjacencymatrixId, "\n");
    }

    fprintf(fAdjacencymatrixId, "\n\n\n\n");

    // Rewiring the system using the rewiring probability

    fprintf(frandomnumberId, "#N = %d, k = %d, p = %f \n", nodes, mean_degree, probability);
    fprintf(frandomnumberId, "S.No i    j    r    re   \n");

    for (i = 0; i < N - 1; i++)
    {
        for (j = i + 1; j < N; j++)
        {
            if (edgematrix[i][j] == 1)
            {
                randomnumber = randomnumbergenerator(max_randomnumber);         //Generate a random number and divide it by max_random number.
                randomnumber = (float)randomnumber / (float)max_randomnumber;   //If normalized value is less than p, remove connection
                if (randomnumber < probability)
                {
                    edgematrix[i][j] = 0;
                    edgematrix[j][i] = 0;
                    Done = 0;
                    while (Done != 1)
        //Done is a flag variable. rewiringnumber stores the index of a random neuron in the network to which neuron 'i' gets rewired to.
        //Self loops and redundant connections are avoided
        //Hence, once we establish a connection which is not a self loop or a redundant connection, Done becomes 1 and we get out of the loop
                    {
                        rewiringnumber = randomnumbergenerator(N - 1);
                        if (rewiringnumber != i && edgematrix[i][rewiringnumber] == 0)  //Eliminating self-loops & redundant connections
                        {
                            edgematrix[i][rewiringnumber] = 1;
                            edgematrix[rewiringnumber][i] = 1;  //Since for an undirectional graph, edgematrix[i][j] = edgematrix[j][i]
                            fprintf(frandomnumberId, "%d    %d    %d    %f    %d\n", 0, i, j, randomnumber, rewiringnumber);
                            Done = 1;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
            else
                continue;
        }
        //printf("Node %d rewired. \n", i+1);
    }

    //Writing into files and printing
    //printf("Starting to write adjacency matrix into the file. \n\n");
    fprintf(fAdjacencymatrixId, "#N = %d, k = %d, p = %f \n", nodes, mean_degree, probability);
    fprintf(fNoConnectionsId, "#N = %d, k = %d, p = %f \n", nodes, mean_degree, probability);

    for (i = 0; i < N; i++)
    {
        no_of_connections = 0;
        for (j = 0; j < N; j++)
        {
            fprintf(fAdjacencymatrixId, "%f   ", edgematrix[i][j]); //Printing Adjacency Matrix of neuron
            if (edgematrix[i][j] == 1)
            {
                no_of_connections = no_of_connections + 1;  //Calculating number of connections of current neuron
            }
        }
        degree[no_of_connections]++;
        connections[i] = connections[i] + no_of_connections;
        fprintf(fAdjacencymatrixId, "\n");
        fprintf(fNoConnectionsId, "%d    %d\n", i + 1, no_of_connections);
    }
    //printf("Finished writing adjacency matrix into the file. \n\n");
    //printf("Finished printing number of connections per neuron. \n\n");

    for (i = 0; i < N; i++) // Iterating through all the nodes in the network
    {
        connections[i] = connections[i] / 2.0;
    }

    fprintf(fAdjacencymatrixId, "\n\n\n\n");
    int countno = 0;

    for (i = 0; i < N - 1; i++)
    {

        for (j = i + 1; j < N; j++)
        {
            if (edgematrix[i][j] == 0 && edgematrix1[i][j] == 1)
            {
                countno++;
            }
        }
    }

    fprintf(fAdjacencymatrixId, "%d", countno);

/*______________________________________________________________________________________________________________________________________*/
    fprintf(ftrial_output, "No of time steps: %d\n", n_steps);

    for (i = 0; i < N; i++)
    {
        V[i] = 0.0;
        k1[i] = 0.0;
        k2[i] = 0.0;
        k3[i] = 0.0;
        k4[i] = 0.0;
        m1[i] = 0.0;
        m2[i] = 0.0;
        m3[i] = 0.0;
        m4[i] = 0.0;
        n1[i] = 0.0;
        n2[i] = 0.0;
        n3[i] = 0.0;
        n4[i] = 0.0;
        h1[i] = 0.0;
        h2[i] = 0.0;
        h3[i] = 0.0;
        h4[i] = 0.0;
        coupling1[i] = 0.0;
        coupling2[i] = 0.0;
        coupling3[i] = 0.0;
        m_noise[i] = 0.0;
        n_noise[i] = 0.0;
        h_noise[i] = 0.0;

        alpha_m[i] = (0.1 * (25 - V[i])) / (exp((25 - V[i]) / 10) - 1);
        beta_m[i] = 4 * exp(-V[i] / 18);
        alpha_h[i] = 0.07 * exp(-V[i] / 20);
        beta_h[i] = 1 / (exp((30 - V[i]) / 10) + 1);
        alpha_n[i] = 0.01 * (10 - V[i]) / (exp((10 - V[i]) / 10) - 1);
        beta_n[i] = 0.125 * exp(-V[i] / 80);

        /*alpha_m[i] = (0.1*(V[i] + 40))/(-exp((-40 - V[i])/10) + 1);
         * beta_m[i] = 4*exp((-V[i] - 65)/18);
         * alpha_h[i] = 0.07*exp((-V[i]-65)/20);
         * beta_h[i] = 1/(exp((-35-V[i])/10) + 1);
         * alpha_n[i] = 0.01*(V[i] + 55)/(-exp((-55-V[i])/10) + 1);
         * beta_n[i] = 0.125*exp((-V[i]-65)/80);
         */

        m[i] = (alpha_m[i] / (alpha_m[i] + beta_m[i]));
        h[i] = (alpha_h[i] / (alpha_h[i] + beta_h[i]));
        n[i] = (alpha_n[i] / (alpha_n[i] + beta_n[i]));
    }

    for (i = 0; i < N; i++)
    {
        sum_coupling = 0.0;
        for (j = 0; j < N; j++)
        {
            sum_coupling = sum_coupling + (edgematrix[i][j] * (V[j] - V[i]));
        }
        coupling[i] = sum_coupling;
    }
    // printf("Done #1\n");
    //Starting calculation using RK4
    for (l = 0; l <= n_steps; l++)
    {
        //printf("%f\n",l*dt );
        fprintf(fV_vs_t_id, "%f\t", l * dt);
        fprintf(fmvalueId, "%f\n", l * dt);
        fprintf(fhvalueId, "%f\n", l * dt);
        fprintf(fnvalueId, "%f\n", l * dt);
        fprintf(fm_noiseId, "%f\t", l * dt);
        for (j = 0; j < N; j++)
        {
            alpha_m[j] = (0.1 * (25 - V[i])) / (exp((25 - V[i]) / 10) - 1);
            beta_m[j] = 4 * exp(-V[i] / 18);
            alpha_h[j] = 0.07 * exp(-V[i] / 20);
            beta_h[j] = 1 / (exp((30 - V[i]) / 10) + 1);
            alpha_n[j] = 0.01 * (10 - V[i]) / (exp((10 - V[i]) / 10) - 1);
            beta_n[j] = 0.125 * exp(-V[i] / 80);

            m_noise[j] = sqrt(((2 * alpha_m[j] * beta_m[j]) / (Nna * xna * (alpha_m[j] + beta_m[j])))) * gaussrandm();
            fprintf(fm_noiseId, "%f\t", m_noise[j]);
            n_noise[j] = sqrt(((2 * alpha_n[j] * beta_n[j]) / (Nk * xk * (alpha_n[j] + beta_n[j])))) * gaussrandn();
            h_noise[j] = sqrt(((2 * alpha_h[j] * beta_h[j]) / (Nna * xna * (alpha_h[j] + beta_h[j])))) * gaussrandh();
            k1[j] = dt * KV(coupling[j], V[j], m[j], h[j], n[j]);
            m1[j] = dt * (Km(V[j], m[j]) + m_noise[j]);
            h1[j] = dt * (Kh(V[j], h[j]) + h_noise[j]);
            n1[j] = dt * (Kn(V[j], n[j]) + n_noise[j]);
            coupling1[j] = dt * Kcoupling(V, edgematrix, nodes, k1, j);
        }
        fprintf(fm_noiseId, "\n");
        for (j = 0; j < N; j++)
        {
            k2[j] = dt * KV(coupling[j] + (0.5 * coupling1[j]), V[j] + (0.5 * k1[j]), m[j] + (0.5 * m1[j]), h[j] + (0.5 * h1[j]),n[j] + (0.5 * n1[j]));
            m2[j] = dt * (Km(V[j] + (0.5 * k1[j]), m[j] + (0.5 * m1[j])) + m_noise[j]);
            h2[j] = dt * (Kh(V[j] + (0.5 * k1[j]), h[j] + (0.5 * h1[j])) + h_noise[j]);
            n2[j] = dt * (Kn(V[j] + (0.5 * k1[j]), n[j] + (0.5 * n1[j])) + n_noise[j]);
            coupling2[j] = dt * Kcoupling(V, edgematrix, nodes, k2, j);
        }

        for (j = 0; j < N; j++)
        {

            k3[j] = dt * KV(coupling[j] + (0.5 * coupling2[j]), V[j] + (0.5 * k2[j]), m[j] + (0.5 * m2[j]), h[j] + (0.5 * h2[j]),n[j] + (0.5 * n2[j]));
            m3[j] = dt * (Km(V[j] + (0.5 * k2[j]), m[j] + (0.5 * m2[j])) + m_noise[j]);
            h3[j] = dt * (Kh(V[j] + (0.5 * k2[j]), h[j] + (0.5 * h2[j])) + h_noise[j]);
            n3[j] = dt * (Kn(V[j] + (0.5 * k2[j]), n[j] + (0.5 * n2[j])) + n_noise[j]);
            coupling3[j] = dt * Kcoupling1(V, edgematrix, nodes, k3, j);
        }

        for (j = 0; j < N; j++)
        {

            k4[j] = dt * KV(coupling[j] + coupling3[j], V[j] + k3[j], m[j] + m3[j], h[j] + h3[j], n[j] + n3[j]);
            m4[j] = dt * (Km(V[j] + k3[j], m[j] + m3[j]) + m_noise[j]);
            h4[j] = dt * (Kh(V[j] + k3[j], h[j] + h3[j]) + h_noise[j]);
            n4[j] = dt * (Kn(V[j] + k3[j], n[j] + n3[j]) + n_noise[j]);
        }

        for (j = 0; j < N; j++)
        {
            V[j] = V[j] + ((k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) / 6);
            m[j] = m[j] + ((m1[j] + 2 * m2[j] + 2 * m3[j] + m4[j]) / 6);
            h[j] = h[j] + ((h1[j] + 2 * h2[j] + 2 * h3[j] + h4[j]) / 6);
            n[j] = n[j] + ((n1[j] + 2 * n2[j] + 2 * n3[j] + n4[j]) / 6);
            fprintf(fV_vs_t_id, "%f\t", V[j]);
            fprintf(fVTid, "%f\t", l * dt);
            fprintf(fVTid, "%f\n", V[j]);
            fprintf(fmvalueId, "%f\t", m[j]);
            fprintf(fhvalueId, "%f\t", h[j]);
            fprintf(fnvalueId, "%f\t", n[j]);
        }
        fprintf(fV_vs_t_id, "\n");
        fprintf(fmvalueId, "\n");
        fprintf(fhvalueId, "\n");
        fprintf(fnvalueId, "\n");
        for (i = 0; i < N; i++)
        {
            sum_coupling = 0.0;
            for (j = 0; j < N; j++)
            {
                sum_coupling = sum_coupling + (edgematrix[i][j] * (V[j] - V[i]));
            }
            coupling[i] = sum_coupling;
        }

    }

    fclose(fAdjacencymatrixId);
    fclose(fV_vs_t_id);
    fclose(fVTid);
    fclose(fNoConnectionsId);
    fclose(frandomnumberId);
    fclose(fmvalueId);
    fclose(fnvalueId);
    fclose(fhvalueId);
    //fclose(fMeanShortestPathId);
    //fclose(fClusteringCoeffId);
//________________________________________________________________________________________________________________________________________
    // printf("Done #2\n");
//Calculation of ISI, spike times, firing correlation, average firing coherence etc.
    double f_correlation[N][N];
    float tmp0 = 0.0;
    float tmp1 = 0.0;
    int s = 0;
    int a = 0;
    int b = 0;
    int c = 0;
    double z = 0.0;
    int smax = 0;
    char ignore[1024];
    double t1 = 0.0;
    double t2 = timewell;
    int no_cycles = (int)(time_max / timewell);
    double sum_total = 0.0;

    for (i = 0; i < N; i++)
    {
        //no_spikes[i] = 0;
        for (j = 0; j < N; j++)
        {
            f_correlation[i][j] = 0.0;
        }
    }

    strcpy(file_path, base_path);
    strcat(file_path, "VT.txt");
    fVTid = fopen(file_path, "r");

    float voltagematrix[n_steps];
    float timematrix[n_steps];

    for (i = 0; i < n_steps; i++)
    {
        voltagematrix[i] = 0.0;
        timematrix[i] = 0.0;
    }

    float tspike[N][n_steps / n_one_cycle];

    for (i = 0; i < N; i++)
        for (j = 0; j < (n_steps / n_one_cycle); j++)
            tspike[i][j] = 0;
    // printf("Done #3\n");
    for (i = 0; i < N; i++)
    {
        //countnotimes = 0;
        s = 0;
        tmp0 = 0.0;
        tmp1 = 0.0;
        // printf("loop0\n");
        for (j = 0; j < i; j++)
        {
            fgets(ignore, sizeof(ignore), fVTid);
            // printf("loop1\n");
        }
        for (l = 0; l < n_steps; l++)
        {
            fscanf(fVTid, "%f %f", &timematrix[l], &voltagematrix[l]);  // reading from file
            // printf("loop2\n");
            for (a = 0; a < N; a++)
            {
                fgets(ignore, sizeof(ignore), fVTid);
                // printf("loop3\n");
            }
        }
        //printf("%f\n",voltagematrix[1500]);
        for (b = 1; b <= n_steps - 1; b++)
        {
            //printf("Here\n");
            //countnotimes = countnotimes + 1;
            tmp0 = voltagematrix[b] - voltagematrix[b + 1];
            tmp1 = voltagematrix[b] - voltagematrix[b - 1];
            // printf("loop4\n");
            if (tmp0 > 0 && tmp1 > 0)
            {
                if (voltagematrix[b] > 70.0)
                {
                    tspike[i][s] = timematrix[b];
                    if (floor(tspike[i][s]) == floor(tspike[i][s - 1]) || floor(tspike[i][s]) == ceil(tspike[i][s - 1]))
                    {
                        tspike[i][s] = 0.0;
                        continue;
                    }
                    fprintf(fspiketimeid, "%f\t", tspike[i][s]);
                    // printf("loop5\n");
                    s = s + 1;
                    no_spikes[i] = s;
                    if (s > smax)
                    {
                        smax = s;
                    }
                }
            }
        }
        //printf("%d\n",countnotimes);
        fprintf(fspiketimeid, "\n");
        // printf("loop6\n");
        rewind(fVTid);
        // printf("loop7\n");
        //  printf("No of spikes of neuron %d: %d\n",i+1,no_spikes[i]);
    }
    // printf("Done #4\n");
    int flag = 0;

    for (i = 0; i < N; i++)
    {
        if (no_spikes[i] == 0)
            flag = 1;
    }

    // if (flag == 1)
    // {
    //     trial = trial - 1;
    //     printf("Re-simulating, no spikes detected\n");
    //     continue;
    // }

    double AvgISI[N];

    double ISI = 0.0;
    int count_isi = 0;

    for (i = 0; i < N; i++)
    {
        AvgISI[i] = 0.0;
    }

    for (i = 0; i < N; i++)
    {
        count_isi = 0;
        for (j = 1; j < smax; j++)
        {
            if (tspike[i][j] == 0.0)
            {
                continue;
            }
            ISI = tspike[i][j] - tspike[i][j - 1];
            AvgISI[i] = AvgISI[i] + ISI;
            count_isi = count_isi + 1;
        }
        AvgISI[i] = AvgISI[i] / count_isi;
    }

    for (i = 0; i < N; i++)
    {
        FinalISI[i] = FinalISI[i] + AvgISI[i];  // ISI averaged over all neurons
    }

    fclose(fspiketimeid);
    int Y[N][no_cycles];

    /*int **Y;
     * Y = (int **)malloc(N*sizeof(float));
     * for(c = 0; c < N; c++)
     * {
     * Y[c] = (int *)malloc(no_cycles * sizeof(int));
     * }
     */

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < no_cycles; j++)
        {
            Y[i][j] = 0;
        }
    }

    for (i = 0; i < N; i++)
    {
        for (a = 0; a < (n_steps / n_one_cycle); a++)   // n_steps/n_one_cycle is value of time bin
        {
            if (tspike[i][a] == 0)
                continue;
            int bin_number = (int)(floor(tspike[i][a]) / timewell); // timewell = n_steps/n_one_cycle
            Y[i][bin_number] = 1;
        }
    }

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < no_cycles; j++)
        {
            fprintf(yid, "%d\t", Y[i][j]);
        }
        fprintf(yid, "\n");
    }

    int sum_spikes = 0;

    for (i = 0; i < N - 1; i++)
    {
        for (j = i + 1; j < N; j++)
        {
            for (l = 0; l < no_cycles; l++)
            {
                if (Y[i][l] == 1 && Y[j][l] == 1)
                {
                    sum_spikes = sum_spikes + 1;
                }
            }
            f_correlation[i][j] = (double)sum_spikes / sqrt(no_spikes[i] * no_spikes[j]);
            f_correlation[j][i] = (double)sum_spikes / sqrt(no_spikes[i] * no_spikes[j]);
            sum_spikes = 0;
        }
    }

    for (i = 0; i < N - 1; i++)
    {
        for (j = i + 1; j < N; j++)
        {
            sum_total = sum_total + f_correlation[i][j];
        }
    }

    sum_total = 2.0 * sum_total / (N * (N - 1));
    firing_coherence = firing_coherence + sum_total;    // population coherence
    fprintf(ftrial_output, "Firing Coherence: %f\n", sum_total);

    fclose(yid);

    int distance[N][N]; //Array containing shortest paths between all pairs of nodes // FLOYD WARSHALL Algorithm implementation
    //int i,j,l;
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            if (edgematrix[i][j] == 0)
            {
                if (i == j)
                {
                    distance[i][j] = 0;
                    distance[j][i] = 0;
                }
                else
                {
                    distance[i][j] = 100;   //100 is just a very large number. Symbolizes infinity.
                    distance[j][i] = 100;
                }
            }
            else
            {
                distance[j][i] = 1;
                distance[i][j] = 1;
            }
        }
    }

    //Calculating shortest paths
    for (l = 0; l < N; l++)
    {
        for (i = 0; i < N; i++)
        {
            for (j = 0; j < N; j++)
            {
                if (distance[i][j] > (distance[i][l] + distance[l][j]))
                {
                    distance[i][j] = distance[i][l] + distance[l][j];
                }
                else
                    continue;
            }
        }
    }

    int max_dist = 0;
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            //      printf("%d\t",distance[i][j]);
            if (distance[i][j] > max_dist)
                max_dist = distance[i][j];
        }
        //  printf("\n");
    }

    double fc_degree[max_dist]; // firing correlation by degree of separation.

    for (i = 0; i < max_dist; i++)
        fc_degree[i] = 0.0;

    double sum_fc_degree = 0.0;
    int count = 0;

    for (i = 1; i <= max_dist; i++)
    {
        sum_fc_degree = 0.0;
        count = 0;
        for (j = 0; j < N - 1; j++)
        {
            for (l = i + 1; l < N; l++)
            {
                if (distance[j][l] == i)
                {
                    sum_fc_degree = sum_fc_degree + f_correlation[j][l];
                    count = count + 1;
                }
            }
        }
        fc_degree[i - 1] = sum_fc_degree / count;
    }

    for (i = 0; i < max_dist; i++)
    {
        fprintf(ftrial_output, "%d:  %f\n", i + 1, fc_degree[i]);
        tot_degree[i] = tot_degree[i] + fc_degree[i];
        count_degree[i] = count_degree[i] + 1;
    }

    fclose(ftrial_output);
    MPI_Send(&(FinalISI[0]), 100, MPI_DOUBLE, rec_proc_rank, 0, MPI_COMM_WORLD);
    MPI_Send(&(no_spikes[0]), 100, MPI_INT, rec_proc_rank, 1, MPI_COMM_WORLD);
    MPI_Send(&(connections[0]), 100, MPI_DOUBLE, rec_proc_rank, 2, MPI_COMM_WORLD);
    MPI_Send(&tot_degree[0], 12, MPI_DOUBLE, rec_proc_rank, 3, MPI_COMM_WORLD);
    MPI_Send(&count_degree[0], 12, MPI_INT, rec_proc_rank, 4, MPI_COMM_WORLD);
    MPI_Send(&firing_coherence, 1, MPI_DOUBLE, rec_proc_rank, 5, MPI_COMM_WORLD);
    MPI_Send(&rec_proc_rank, 1, MPI_INT, rec_proc_rank, 6, MPI_COMM_WORLD);

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

MPI_Finalize();
return 0;
}
示例#3
0
/**
  * The optimal community structure is a subdivision of the network into
  * nonoverlapping groups of nodes in a way that maximizes the number of
  * within-group edges, and minimizes the number of between-group edges.
  * The modularity is a statistic that quantifies the degree to which the
  * network may be subdivided into such clearly delineated groups.
  *
  * The Louvain algorithm is a fast and accurate community detection
  * algorithm (as of writing). The algorithm may also be used to detect
  * hierarchical community structure.
  *
  *     Input:      W       undirected (weighted or binary) connection matrix.
  *                 gamma,  modularity resolution parameter (optional)
  *                             gamma>1     detects smaller modules
  *                             0<=gamma<1  detects larger modules
  *                             gamma=1     (default) classic modularity
  *
  *     Outputs:    Ci,     community structure
  *                 Q,      modularity

  * Note: Ci and Q may vary from run to run, due to heuristics in the
  * algorithm. Consequently, it may be worth to compare multiple runs.
  *
  * Reference: Blondel et al. (2008)  J. Stat. Mech. P10008.
  *           Reichardt and Bornholdt (2006) Phys Rev E 74:016110.
  */
urowvec Connectome::modularity_louvain(mat W, double *Qopt, double gamma)
{
    uint N = W.n_rows, h = 1, n = N, u =0, ma =0, mb =0;
    double s = accu(W), wm = 0, max_dQ = -1;
    uvec M, t;
    rowvec dQ;
    field<urowvec> Ci(20);
    Ci(0) = urowvec(); Ci(1) = linspace<urowvec>(0,n-1,n);
    rowvec Q = "-1,0";

    while (Q(h)-Q(h-1) > 1e-10) {
        rowvec K = sum(W,0), Km = K;
        mat Knm = W;

        M = linspace<uvec>(0,n-1,n);

        bool flag = true;

        while (flag) {
            flag = false;

            arma_rng::set_seed_random();
            t = shuffle(linspace<uvec>(0,n-1,n));
            for (uint i =0;i<n;++i) {
                u = t(i);
                ma = M(u);
                dQ = Knm.row(u) - Knm(u,ma)+W(u,u)-
                        gamma*K(u)*(Km-Km(ma)+K(u))/s;
                dQ(ma) = 0;
                max_dQ = dQ.max();
                mb = as_scalar(find(dQ == max_dQ,1));
                if (max_dQ > 1e-10) {
                    flag = true;
                    M(u) = mb;

                    Knm.col(mb) += W.col(u);
                    Knm.col(ma) -= W.col(u);
                    Km(mb) += K(u);
                    Km(ma) -= K(u);
                }
            }
        }
        Ci(++h) = zeros<urowvec>(1,N);
        M = matlabUnique(M);
        for (uint u=0;u<n;++u) {
            Ci(h)(find(Ci(h-1) == u)).fill(M(u));
        }
        n = M.max()+1;
        mat w = zeros(n,n);
        for (uint u =0;u<n;++u)
            for (uint v=u;v<n;++v) {
                wm = accu(W(find(M==u),find(M==v)));
                w(u,v) = wm;
                w(v,u) = wm;
            }
        W = w;
        Q.resize(h+1);
        Q(h) = trace(W)/s - gamma*accu((W*W)/(s*s));
    }
    *Qopt = Q(h);
    return Ci(h);
}
int main()
{
		

	FILE *fV_vs_t_id;
	clock_t start, end;
	fV_vs_t_id = fopen("V_vs_t.txt", "w");
		
	FILE *out1;
	out1 = fopen("m.txt", "w");
		
	FILE *out2;
	out2 = fopen("h.txt", "w");

	FILE *out3;
	out3 = fopen("n.txt", "w");
		
	FILE *fI_vs_t_id;
	fI_vs_t_id = fopen("I_vs_t.txt", "w");
		

  	double runTime;
	double dt,T,w,freq;
 //	double t_max;
       // double	freq_min, freq_max, dfreq ;
	double  time;
	double GNa,GK,GL,VNa,VK,VL,c,R;
	double alpham1,betam1,alphah1,betah1,alphan1,betan1 ;
	double k11,m11,n11,h11,Iext11;
	double k12,m12,n12,h12,Iext12;
	double k13,m13,n13,h13,Iext13;
	double k14,m14,n14,h14;
	long  i,j, jf, jI0;
	long  n_max;
	//double Iext0_min, Iext0_max, dIext0;
	double Iext0;
       // long  Num_I0, Num_freq;
	char *forcing_param[30];

	double *V1 ;
	double *m1 ;
	double *h1 ;
	double *n1 ;
	double *Iext;

	
	start = clock();



// ************************ Fix neuron parameters*****************************************************
	GNa=120 ;
	GK = 36;
	GL=0.3;
	R = 30;
	VNa = 115;
	VK = -12;
	VL=10.5995;
	c = 1;
// *********************** Input parameter values (read from file below)*****************************************************
#include</home/himanshu/NeuronSimulations/OneFrequency/Code/WorkingDir/par_HH.h>




// *********************** Start the FREQUENCY loop **************************************************************		
	freq = freq_min;
	for(jf = 0 ; jf < Num_freq  ; jf++) { 

		//freq = freq + dfreq;

		// ************************** Calculate T, dt, n_max and w (all of which depend on freq - loop is over frequency) *********

		// Time period
		T=(1/freq); // in seconds
		printf("Time period (in seconds) = %3.10f \n \n",T);

		// Time step
		dt=(T/1000); // in seconds (time step is always chosen as (1/1000)th of the time period of ext current)
		printf("Time step (in seconds) = %3.10f \n \n",dt);

		// Number of time steps
		n_max = t_max*freq*1000; // n_max = t_max / dt , where dt = T/1000 (1 time period divided into 1000 time intervals), and T = 1/freq
		printf("Number of time steps  = %d \n \n",n_max);

		// Anglular frequency
		 w = freq*2*M_PI; // angular frequency (radians per second)
		printf("Angular frequency (rad/second) = %3.10f \n \n",w);

	
		// **************************** convert parameters to milliseconds (from seconds) *********************************
	
		// Anglular frequency
		w=(w/1000); // angular frequency (radians per millisecond)
		printf("Angular frequency (rad/milli-second) = %3.10f \n \n",w);
	

		// Time step
		dt=dt*1000; // in milliseconds. Factor of 1000 converts dt to milliseconds.
		printf("Time step (in milli-second) = %3.10f \n \n",dt);

	        V1 = (double *)malloc(n_max*sizeof(double));
		m1 = (double *)malloc(n_max*sizeof(double));
		h1 = (double *)malloc(n_max*sizeof(double));
		n1 = (double *)malloc(n_max*sizeof(double));
		Iext = (double *)malloc(n_max*sizeof(double));

	
		// ***************************** Prepare simulation for a fresh value of forcing amplitude ***************************************
		Iext0 = Iext0_min;
		for(jI0 = 0 ; jI0 < Num_I0  ; jI0++) {  // Loop over a range of current (external) amplitudes (Max number of current values = Num_I0)
			
			 printf("jI0= %f",jI0);
		
			 // Iext0 = Iext0 + dIext0;  External current will be updated at the end of the loop


			 //  ************* Initialize time, V[], m1, h1, n1 before starting RK4 *********************************
			 // Bring time back to zero
			 time=0;		 

			 // Bring back voltage and gate variables back to rest state
			 V1[0] = 0; 		 
			 alpham1 = (0.1*(25-V1[0]))/(exp((25 - V1[0])/10) - 1);
			 betam1 = 4*exp(-V1[0]/18);
			 alphah1 = 0.07*exp(-V1[0]/20);
			 betah1 = 1/(exp((30-V1[0])/10) + 1);
			 alphan1 = 0.01*(10-V1[0])/(exp((10-V1[0])/10) - 1);
			 betan1 = 0.125*exp(-V1[0]/80);
			 m1[0] = (alpham1/(alpham1 + betam1));
			 h1[0] = (alphah1/(alphah1 + betah1));
			 n1[0] = (alphan1/(alphan1 + betan1));

		
		         fprintf(fV_vs_t_id,"\n");
		         fprintf(fV_vs_t_id,"\n");
		         fprintf(fV_vs_t_id,"%s %f \n","#Iext0=",Iext0);
			 fprintf(fV_vs_t_id,"%s %f \n","#Freq=",freq);
			 fprintf(fV_vs_t_id,"%d %f %f \n",0,time*0.00,V1[0]);

			 fprintf(fI_vs_t_id,"\n");
		         fprintf(fI_vs_t_id,"\n");
		         fprintf(fI_vs_t_id,"%s %f \n","#Iext0=",Iext0);
			 fprintf(fI_vs_t_id,"%s %f \n","#Freq=",freq);

		         

			 // ***************************** START TIME STEPPING WITH RK4 ***************************************
			 for(i=0; i<n_max ; i++) // Loop over time for a chosen forcing parameter values
			 {
				  //printf("i= %d \n",i);
				 //time = time + dt;
				 time = (i+1)*dt;
				 //Time[i] = time ;

				 Iext[i]=Iext0*cos(w*time);


				 k11 = dt*KV(Iext[i],V1[i],m1[i],h1[i],n1[i],GNa,GK,GL,VNa,VK,VL,c);
	   			 m11 = dt*Km(V1[i],m1[i]);
	    			 h11 = dt*Kh(V1[i],h1[i]);
	    			 n11 = dt*Kn(V1[i],n1[i]);
	    			 Iext11=dt*KIext(time,w,Iext0);

				 k12 = dt*KV(Iext[i]+0.5*Iext11 ,V1[i]+(0.5*k11),m1[i]+(0.5*m11),h1[i]+(0.5*h11),n1[i]+(0.5*n11),GNa,GK,GL,VNa,VK,VL,c);
	    			 m12 = dt*Km(V1[i]+(0.5*k11),m1[i]+(0.5*m11));
	    			 h12 = dt*Kh(V1[i]+(0.5*k11),h1[i]+(0.5*h11));
	   			 n12 = dt*Kn(V1[i]+(0.5*k11),n1[i]+(0.5*n11));
	  			 Iext12=dt*KIext(time+0.5*dt,w,Iext0);

				 k13 = dt*KV(Iext[i]+0.5*Iext12 ,V1[i]+(0.5*k12),m1[i]+(0.5*m12),h1[i]+(0.5*h12),n1[i]+(0.5*n12),GNa,GK,GL,VNa,VK,VL,c);
	    			 m13 = dt*Km(V1[i]+(0.5*k12),m1[i]+(0.5*m12));
	    			 h13 = dt*Kh(V1[i]+(0.5*k12),h1[i]+(0.5*h12));
	   			 n13 = dt*Kn(V1[i]+(0.5*k12),n1[i]+(0.5*n12));
	    			 Iext13=dt*KIext(time+0.5*dt,w,Iext0);

				 k14 = dt*KV(Iext[i]+Iext13 ,V1[i]+k13,m1[i]+m13,h1[i]+h13,n1[i]+n13,GNa,GK,GL,VNa,VK,VL,c);
	    			 m14 = dt*Km(V1[i]+k13,m1[i]+m13);
	   		         h14 = dt*Kh(V1[i]+k13,h1[i]+h13);
	   		         n14 = dt*Kn(V1[i]+k13,n1[i]+n13);


				V1[i+1] = V1[i] + ((k11 + 2*k12 + 2*k13 + k14)/6);
	    			m1[i+1] = m1[i] + ((m11 + 2*m12 + 2*m13 + m14)/6);
	   			h1[i+1] = h1[i] + ((h11 + 2*h12 + 2*h13 + h14)/6);
	   			n1[i+1] = n1[i] + ((n11 + 2*n12 + 2*n13 +n14)/6);
					
				fprintf(fV_vs_t_id,"%d %f %f \n",i+1,time*0.001,V1[i+1]);
				//fprintf(out1," %f %f\n",m1[i+1],time);
				//fprintf(out2," %f %f\n",h1[i+1],time);
				//fprintf(out3," %f %f\n",n1[i+1],time);
				fprintf(fI_vs_t_id," %d %f %f \n",i+1,time*0.001,Iext[i]);
	 					
						 
			} // end of RK4 loop

			Iext0 = Iext0 + dIext0; // change the forcing amplitude value and simulate once again.
		} // end of amplitude loop		
  	
		freq = freq + dfreq; // change the forcing frequency value and simulate once again.
  	} // end of frequency loop

		/*	Plotter p = pl_alloc();
			pl_add(p, n_max, Time, V1, "g*-");
		        pl_plot(p);

		//}
				//fclose(ofp);
				end = clock();
  				runTime = (end - start) / (double) CLOCKS_PER_SEC ;
  				printf ("%f\n", runTime);
                                printf ("%d\n", Num_I0);
  				getchar(); */
	fclose(fV_vs_t_id);
	fclose(out1);
	fclose(out2);
	fclose(out3);
	fclose(fI_vs_t_id); 
	return 0; 
}
//------------------------------------------------------------------------------
//void CKonst(int lmax, double *cma, double *cpa, double *cza,
//      double *KmLm, double *KoLo, double *KpLM,
//      double *KmlM, double *Kolo, double *Kplm){
//   int i=0;
//   int l, m;
//   for(l=0;l<=lmax;l++){
//      for(m=-l;m<=l;m++){
//         cma[i]=cm(l,m);
//         cza[i]=m;
//         cpa[i]=cp(l,m);
//         KmLm[i]=Km(l+1,m,m-1);
//         KoLo[i]=Ko(l+1,m,m  );
//         KpLM[i]=Kp(l+1,m,m+1);
//         KmlM[i]=Km(l  ,m,m+1);
//         Kolo[i]=Ko(l  ,m,m  );
//         Kplm[i]=Kp(l  ,m,m-1);
//         i++;
//      }
//   }
//}
////------------------------------------------------------------------------------
//// CALCULATION OF CONSTANTS - ONE MORE LOOP - POSITION INDEPENDENT
////------------------------------------------------------------------------------
//// L DEPENDENT
//double CL[LMAX];
//double LL[LMAX];
//// CONSTANTS FOR X
//double CM[LMAX];
//double CZ[LMAX];
//double CP[LMAX];
//// CONSTANTS FOR Y AND V
//KmLm[LMAX];
//KoLo[LMAX];
//KpLM[LMAX];
//KmlM[LMAX];
//Kolo[LMAX];
//Kplm[LMAX];
//// SINGLE LOOP
//for(int l=1;l<=lmax;l++){
//   for(int m=-l; m<=l; m++){
//      CL[jlm(l,m)]=l;
//      LL[jlm(l,m)]=2*l+1;
//      CM[jlm(l,m)]=cm(l,m);
//      CZ[jlm(l,m)]=m;
//      CP[jlm(l,m)]=cp(l,m);
//      KmLm[jlm(l,m)]=Km(l+1,m,m-1);
//      KoLo[jlm(l,m)]=Ko(l+1,m,m  );
//      KpLM[jlm(l,m)]=Kp(l+1,m,m+1);
//      KmlM[jlm(l,m)]=Km(l  ,m,m+1);
//      Kolo[jlm(l,m)]=Ko(l  ,m,m  );
//      Kplm[jlm(l,m)]=Kp(l  ,m,m-1);
//   }
//}
//------------------------------------------------------------------------------
// POSITION DEPENDENT CALCULATIONS - MULTIPLES LOOPS - COMPLETE CALCULATIONS
//------------------------------------------------------------------------------
void VectorSphericalWaveFunctions(double *k,double *x, double *y, double *z,int *lmax, 
                    double complex *GTE, double complex *GTM,
                    double complex *Em, double complex *Ez, double complex *Ep,
                    double complex *Hm, double complex *Hz, double complex *Hp
                    ){
//   printf("%d\t%E\t%E\t%E\t%E\n",*lmax+1,*k,*x,*y,*z);
   int l,m;
   int LMAX=*lmax*(*lmax+2);
   int LMAXE=(*lmax+1)*(*lmax+3);
   double cph; 
   double sph;
   double rho=sqrt(*x*(*x)+*y*(*y));
   double r=sqrt(rho*rho+*z*(*z));
   double sth=rho/r;
   double cth=*z/r;
   if((*x==0)&&(*y==0)){
      cph=1;
      sph=0;
   }else{
      cph=*x/rho;
      sph=*y/rho;
   }
   // Spherical Bessel Funtions
   double JLM[*lmax+2];
  // double *JLM=&JLM0[0];
   gsl_sf_bessel_jl_steed_array(*lmax+1,*k*r,JLM);
   /* CALCULATIONS OK
   for(l=0;l<(*lmax+2);l++){
         printf("%d\t%f\t%E\n",l,*k*r,JLM[l]);
   } 
   */
   // Qlm - primeiros 4 termos
   double Qlm[LMAXE];
   Qlm[jlm(0, 0)]=1/sqrt(4*M_PI);
   Qlm[jlm(1, 1)]=-gammaQ(1)*sth*Qlm[jlm(0,0)]; // Q11
   Qlm[jlm(1, 0)]=sqrt(3.0)*cth*Qlm[jlm(0,0)];  // Q10
   Qlm[jlm(1,-1)]=-Qlm[jlm(1,1)];               // Q11*(-1)
   // Complex Exponencial for m=-1,0,1
   double complex Eim[2*(*lmax)+3];
   Eim[*lmax-1]=(cph-I*sph);
   Eim[*lmax  ]=1+I*0;
   Eim[*lmax+1]=(cph+I*sph);
   // Ylm - primeiros 4 termos
   double complex Ylm[LMAXE];
   Ylm[jlm(0, 0)]=Qlm[jlm(0, 0)];
   Ylm[jlm(1,-1)]=Qlm[jlm(1,-1)]*Eim[*lmax-1];
   Ylm[jlm(1, 0)]=Qlm[jlm(1, 0)];
   Ylm[jlm(1, 1)]=Qlm[jlm(1, 1)]*Eim[*lmax+1];
   /* OK jl, Qlm, Ylm
   for(l=0;l<2;l++){
      for(m=-l;m<=l;m++){
         printf("%d\t%d\t%d\t%f\t%f\t%f+%fi\n",l,m,jlm(l,m),JLM[jlm(l,m)],Qlm[jlm(l,m)],creal(Ylm[jlm(l,m)]),cimag(Ylm[jlm(l,m)]));
      }
   }
   printf("======================================================================\n");
   */
   // VECTOR SPHERICAL HARMONICS
   double complex XM; //[LMAX];
   double complex XZ; //[LMAX];
   double complex XP; //[LMAX];
   double complex YM; //[LMAX];
   double complex YZ; //[LMAX];
   double complex YP; //[LMAX];
   double complex VM; //[LMAX];
   double complex VZ; //[LMAX];
   double complex VP; //[LMAX];
   // HANSEN MULTIPOLES
   double complex MM; //[LMAX];
   double complex MZ; //[LMAX];
   double complex MP; //[LMAX];
   double complex NM; //[LMAX];
   double complex NZ; //[LMAX];
   double complex NP; //[LMAX];
   // OTHERS
   double kl;
   // MAIN LOOP
   for(l=1;l<=(*lmax);l++){
//------------------------------------------------------------------------------
      //Qlm extremos positivos um passo a frente
      Qlm[jlm(l+1, l+1)]=-gammaQ(l+1)*sth*Qlm[jlm(l,l)];
      Qlm[jlm(l+1, l  )]= deltaQ(l+1)*cth*Qlm[jlm(l,l)];
      //Qlm extremos negativos um passo a frente
      Qlm[jlm(l+1,-l-1)]=pow(-1,l+1)*Qlm[jlm(l+1, l+1)];
      Qlm[jlm(l+1,-l  )]=pow(-1,l  )*Qlm[jlm(l+1, l  )];
      // Exponenciais um passo a frente
      Eim[*lmax+l+1]=Eim[*lmax+l]*(cph+I*sph);
      Eim[*lmax-l-1]=Eim[*lmax-l]*(cph-I*sph);
      // Harmonicos esfericos extremos um passo a frente
      Ylm[jlm(l+1, l+1)]=Qlm[jlm(l+1, l+1)]*Eim[*lmax+l+1];
      Ylm[jlm(l+1, l  )]=Qlm[jlm(l+1, l  )]*Eim[*lmax+l  ];
      Ylm[jlm(l+1,-l-1)]=Qlm[jlm(l+1,-l-1)]*Eim[*lmax-l-1];
      Ylm[jlm(l+1,-l  )]=Qlm[jlm(l+1,-l  )]*Eim[*lmax-l  ];
      // others
      kl=1/(sqrt(l*(l+1)));
      for(m=0; m<l; m++){
      // Demais valores de Qlm e Ylm
         Qlm[jlm(l+1, m)]=alfaQ(l+1,m)*cth*Qlm[jlm(l,m)]-betaQ(l+1,m)*Qlm[jlm(l-1,m)];
         Qlm[jlm(l+1,-m)]=pow(-1,m)*Qlm[jlm(l+1, m)];
         Ylm[jlm(l+1, m)]=Qlm[jlm(l+1, m)]*Eim[*lmax+m];
         Ylm[jlm(l+1,-m)]=Qlm[jlm(l+1,-m)]*Eim[*lmax-m];
      }
//------------------------------------------------------------------------------
//      for(m=-(l+1); m<=(l+1); m++){
//         Ylm[jlm(l+1,m)]=Qlm[jlm(l+1,m)]*Eim[*lmax+m];
//      }
//      for(m=-l; m<=l; m++){
//         printf("%d\t%d\t%d\t%f\t%f+%fi\t%f+%fi\n",l,m,jlm(l,m)+1,Qlm[jlm(l,m)],creal(Eim[*lmax+m]),cimag(Eim[*lmax+m]),creal(Ylm[jlm(l,m)]),cimag(Ylm[jlm(l,m)]));
//      }
//------------------------------------------------------------------------------
      for(int m=-l; m<=l; m++){
         XM=kl*cm(l,m)*Ylm[jlm(l,m-1)]/sqrt(2);
         XZ=kl*m*Ylm[jlm(l,m  )];
         XP=kl*cp(l,m)*Ylm[jlm(l,m+1)]/sqrt(2);
//         printf("--------X--------------------------------\n");
         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(XM),cimag(XM));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(XZ),cimag(XZ));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(XP),cimag(XP));
         YM=(-Kp(l,m,m-1)*Ylm[jlm(l,m-1)]+Km(l+1,m,m-1)*Ylm[jlm(l+1,m-1)])/sqrt(2);
         YZ=  Ko(l,m,m  )*Ylm[jlm(l,m  )]+Ko(l+1,m,m  )*Ylm[jlm(l+1,m  )];
         YP=( Km(l,m,m+1)*Ylm[jlm(l,m+1)]-Kp(l+1,m,m+1)*Ylm[jlm(l+1,m+1)])/sqrt(2);
//        printf("--------Y--------------------------------\n");
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(YM),cimag(YM));
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(YZ),cimag(YZ));
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(YP),cimag(YP));
         VM=kl*(-(l+1)*Kp(l,m,m-1)*Ylm[jlm(l,m-1)]-l*Km(l+1,m,m-1)*Ylm[jlm(l+1,m-1)])/sqrt(2);
         VZ=kl*( (l+1)*Ko(l,m,m  )*Ylm[jlm(l,m  )]-l*Ko(l+1,m,m  )*Ylm[jlm(l+1,m  )]);
         VP=kl*( (l+1)*Km(l,m,m+1)*Ylm[jlm(l,m+1)]+l*Kp(l+1,m,m+1)*Ylm[jlm(l+1,m+1)])/sqrt(2);
//        printf("--------V--------------------------------\n");
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(VM),cimag(VM));
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(VZ),cimag(VZ));
//        printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(VP),cimag(VP));
         // CALCULATION OF HANSEM MULTIPOLES
         MM=JLM[l]*XM;
         MZ=JLM[l]*XZ;
         MP=JLM[l]*XP;
//         printf("--------M--------------------------------\n");
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(MM),cimag(MM));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(MZ),cimag(MZ));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(MP),cimag(MP));
         NM=((l+1)*JLM[l-1]-l*JLM[l+1])*VM/(2*l+1)+sqrt(l*(l+1))*JLM[l]*YM;
         NZ=((l+1)*JLM[l-1]-l*JLM[l+1])*VZ/(2*l+1)+sqrt(l*(l+1))*JLM[l]*YZ;
         NP=((l+1)*JLM[l-1]-l*JLM[l+1])*VP/(2*l+1)+sqrt(l*(l+1))*JLM[l]*YP;
//         printf("--------N--------------------------------\n");
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(NM),cimag(NM));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(NZ),cimag(NZ));
//         printf("%d\t%d\t%d\t%f+%fi\n",l,m,jlm(l,m),creal(NP),cimag(NP));
         // CALCULATION OF THE ELECTROMAGNETIC FIELDS
         *Em=*Em+MM*GTE[jlm(l,m)]-NM*GTM[jlm(l,m)]; 
         *Ez=*Ez+MZ*GTE[jlm(l,m)]-NZ*GTM[jlm(l,m)];
         *Ep=*Ep+MP*GTE[jlm(l,m)]-NP*GTM[jlm(l,m)];
         *Hm=*Hm+MM*GTM[jlm(l,m)]+NM*GTE[jlm(l,m)]; 
         *Hz=*Hz+MZ*GTM[jlm(l,m)]+NZ*GTE[jlm(l,m)];
         *Hp=*Hp+MP*GTM[jlm(l,m)]+NP*GTE[jlm(l,m)];
      }
   }
}
示例#6
0
int
PFEMElement2D::update()
{
    // get nodal coordinates
    double x[3], y[3];
    for(int a=0; a<3; a++) {
        const Vector& coord = nodes[2*a]->getCrds();
        const Vector& disp = nodes[2*a]->getTrialDisp();
        x[a] = coord(0) + disp(0);
        y[a] = coord(1) + disp(1);
    }

    // get c and d
    double cc[3], dd[3];
    cc[0] = y[1]-y[2];
    dd[0] = x[2]-x[1];
    cc[1] = y[2]-y[0];
    dd[1] = x[0]-x[2];
    cc[2] = y[0]-y[1];
    dd[2] = x[1]-x[0];

    // get Jacobi
    double J = cc[0]*dd[1]-dd[0]*cc[1];

    if(fabs(J)<1e-15) {
        opserr<<"WARNING: element area is nearly zero";
        opserr<<" -- PFEMElement2D::update\n";
	for (int i=0; i<3; i++) {
	    opserr<<"node "<<ntags[2*i]<<"\n";
	    opserr<<"x = "<<x[i]<<" , y = "<<y[i]<<"\n";
	}

        return -1;
    }

    // get M
    M = rho*J*thickness/6.0;
    Mp = (kappa<=0? 0.0 : J*thickness/kappa/24.0);
    double Mb = 9.*rho*J*thickness/40.0;

    // get Km
    Km.Zero();
    double fact = mu*thickness/(6.*J);
    for (int a=0; a<3; a++) {
	for (int b=0; b<3; b++) {
	    Km(2*a,2*b) = fact*(4*cc[a]*cc[b]+3*dd[a]*dd[b]); // Kxx
	    Km(2*a,2*b+1) = fact*(3*dd[a]*cc[b]-2*cc[a]*dd[b]); // Kxy
	    Km(2*a+1,2*b) = fact*(3*cc[a]*dd[b]-2*dd[a]*cc[b]); // Kyx
	    Km(2*a+1,2*b+1) = fact*(3*cc[a]*cc[b]+4*dd[a]*dd[b]); // Kyy
	}
    }

    // get Kb
    Matrix Kb(2,2);
    fact = 27.*mu*thickness/(40.*J);
    double cc2 = 0., dd2 = 0., cd2 = 0.;
    for(int a=0; a<3; a++) {
	cc2 += cc[a]*cc[a];
	dd2 += dd[a]*dd[a];
	cd2 += cc[a]*dd[a];
    }
    Kb(0,0) = fact*(4*cc2+3*dd2); // Kxx
    Kb(0,1) = fact*cd2; // Kxy
    Kb(1,0) = fact*cd2; // Kyx
    Kb(1,1) = fact*(3*cc2+4*dd2); // Kyy

    // get Gx and Gy
    Gx.Zero(); Gy.Zero();
    fact = thickness/6.0;
    for (int a=0; a<3; a++) {
	Gx(a) = cc[a]*fact;
	Gy(a) = dd[a]*fact;
    }

    // get Gb
    Matrix Gb(2,3);
    fact = -9.*thickness/40.0;
    for (int a=0; a<3; a++) {
	Gb(0,a) = cc[a]*fact;
	Gb(1,a) = dd[a]*fact;
    }

    // get S
    S.Zero();
    if (ops_Dt > 0) {
	Kb(0,0) += Mb/ops_Dt;
	Kb(1,1) += Mb/ops_Dt;
    }
    if (Kb(0,0)!=0 && Kb(1,1)!=0) {
	this->inverse(Kb);
    }
    S.addMatrixTripleProduct(0.0, Gb, Kb, 1);

    // get F
    F.Zero();
    fact = rho*J*thickness/6.0;
    F(0) = fact*b1;
    F(1) = fact*b2;

    // get Fb
    Vector Fb(2);
    fact = 9.*rho*J*thickness/40.;
    Fb(0) = fact*b1;
    Fb(1) = fact*b2;

    // get Fp
    Fp.Zero();
    Fp.addMatrixTransposeVector(0.0, Gb, Kb*Fb, -1);

    return 0;
}