示例#1
0
/*****************************************************************************
 函 数 名  : hi6559_om_log_save
 功能描述  : 记录hi6559的异常信息
 输入参数  : @hi6559_om_log_flag Log类型
 输出参数  : 无
 返 回 值  : 无
*****************************************************************************/
void hi6559_om_log_save(pmu_om_log_e hi6559_om_log_flag)
{
    switch(hi6559_om_log_flag)
    {
        case PMU_OM_LOG_START:
            print2file(PMU_OM_LOG, "system start....\n");
            break;
        case PMU_OM_LOG_EXC:
            break;
        default:
            break;
    }

    return;
}
示例#2
0
/*****************************************************************************
 函 数 名  : hi6559_uvp_die_handle
 功能描述  : 欠压2.5V处理函数,电压低于PMU所能容忍的阈值时所要进行的处理(按道
             理本函数调用到,系统就会挂)
 输入参数  : @para 参数指针
 输出参数  : 无
 返 回 值  : 无
 调用函数  :
 被调函数  : bbstar中断处理任务
*****************************************************************************/
void hi6559_uvp_die_handle(void* para)
{
    para = para;

    pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET);
    /*记录om log */
    /* hi6559_om_log_save(PMU_OM_LOG_EXC); */
    print2file(PMU_OM_LOG, "pmu_hi6559:vsys under 2.5v !\n");

    /* 清除非下电reg */
    bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET));
    pmic_print_error("\n**********hi6559_uvp_2p5_isr**********\n");

    return;/*lint !e438*/
}
示例#3
0
/*****************************************************************************
 函 数 名  : hi6559_ovp_handle
 功能描述  : 过压处理函数
 输入参数  : @para 参数指针
 输出参数  : 无
 返 回 值  : 无
*****************************************************************************/
void hi6559_ovp_handle(void* para)
{
    para = para;

    pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_OVER_6P0_OFFSET);

    /* 记录om log */
    /* hi6559_om_log_save(PMU_OM_LOG_EXC); */
    print2file(PMU_OM_LOG,"pmu_hi6559:vsys over 6.0v last time!\n");

    /* 清除非下电reg */
    bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_OVER_6P0_OFFSET));
    pmic_print_error("\n**********hi6559_ovp_isr**********\n");

    return;/*lint !e438*/
}
示例#4
0
/*****************************************************************************
 函 数 名  : hi6559_otp_handle
 功能描述  : 过温处理函数
 输入参数  : @para 参数指针
 输出参数  : 无
 返 回 值  : 无
*****************************************************************************/
void hi6559_otp_handle(void* para)
{
    s32 i = 0;

    para = para;

    pmic_print_error("hi6559:temperature overflow (>125℃)!\n");

    /*由nv控制过温是否关闭*/
    pmu_hi6559_om_data[0] |= (0x01 << HI6559_OTMP_125_OFFSET);
    
    /*根据nv配置,决定是否关闭非核心电源,后续增加产品形态相关特殊处理*/
    if(pmu_exc_pro.ulOtpCurIsOff)
    {
        for(i = PMIC_HI6559_VOLT_MIN; i < PMIC_HI6559_VOLT_MAX; i++)
        {
            if(pmu_exc_pro.VoltProConfig[i].VoltOtpIsOff)
            {
                pmic_print_error("hi6559:volt id %d will be closed !\n",i);
                bsp_hi6559_volt_disable(i);
            }
        }
    }
    
    if(pmu_exc_pro.ulOtpIsRst)
    {
        pmic_print_error("hi6559:system will be restart!\n");
        system_error(DRV_ERRNO_PMU_OVER_TEMP, PMU_STATE_OVER_TEMP, 0, NULL, 0);
    }

    /* 记录om log */
    /* hi6559_om_log_save(PMU_OM_LOG_EXC); */
    print2file(PMU_OM_LOG, "pmu_hi6559:temperature overflow (>125℃)!\n");
    
    /*clear np int */
    bsp_hi6559_reg_write(HI6559_NP_SCP_RECORD1_OFFSET, (0x01 << HI6559_OTMP_125_OFFSET));
    pmic_print_error("\n**********hi6559_otp_isr**********\n");

    return;/*lint !e438*/
}
示例#5
0
/*****************************************************************************
 函 数 名  : hi6559_uvp_warning_handle
 功能描述  : 欠压处理函数2.85/3.0,电压低于设定的告警阈值,所要进行的处理
 输入参数  : void
 输出参数  : 无
 返 回 值  : void
 调用函数  :
 被调函数  : bbstar中断处理任务
*****************************************************************************/
void hi6559_uvp_warning_handle(void* para)
{
    para = para;
    pmu_hi6559_om_data[0] |= (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET);

    /* 记录om log */
    /* hi6559_om_log_save(PMU_OM_LOG_EXC); */
    print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.85/3.0v !\n");

    /* 根据nv配置确定是否重启 */
    if(pmu_exc_pro.ulUvpIsRst)
    {
        pmic_print_error("hi6559:system will be restart!\n");
        system_error(DRV_ERRNO_PMU_UNDEF_VOL, PMU_STATE_UNDER_VOL, 0, NULL, 0);
    }

    /*清除非下电reg,write 1 clear*/
    bsp_hi6559_reg_write(HI6559_NP_IRQ1_RECORD_OFFSET, (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET));
    pmic_print_error("**********hi6559_uvp_2p85_isr**********\n");

    return;/*lint !e438*/
}
示例#6
0
/*****************************************************************************
 函 数 名  : hi6559_ocp_scp_handle
 功能描述  : 过流处理函数
 输入参数  : @para 参数指针
 输出参数  : 无
 返 回 值  : 无
*****************************************************************************/
void hi6559_ocp_scp_handle(void* para)
{
    u32 volt_need_off = 0;
    u32 *pmu_ocp_flag = (u32 *)SHM_PMU_OCP_INFO_ADDR;   /* 过流,需要关闭的过流源 */
    s32 ret = ERROR;
    u8 a_ucRecordReg[HI6559_NP_OCP_SCP_REG_NUM] = {0};  /* 过流寄存器读取值 */
    u8 i = 0;
    u8 j = 0;
    
    /*lint --e{690,831}*/
    para = para;

    pmic_print_error("******* hi6559_current_overflow! **********\n");

    for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++)
    {
        bsp_hi6559_reg_read((HI6559_NP_SCP_RECORD1_OFFSET + i), &a_ucRecordReg[i]);
        
        /* 在中断处理任务中,是否需要加锁? */
        pmu_hi6559_om_data[i + 3] |= a_ucRecordReg[i];
    }
    
    /* 检查所有SCP_RECORD和OCP_RECORD中的状态, 根据nv配置进行安全处理 */
    /* BUCK短路检查,0x18寄存器 */
    for (j = 0; j < HI6559_NP_SCP_RECORD1_CONT_NUM; j++)
    {
         if (a_ucRecordReg[0] & (u8)((u32)0x1 << reg_np_scp_record1_cont[j].bit_ofs))  /*lint !e690,!e831*/
         {
            volt_need_off |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id);
            *pmu_ocp_flag |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id);

            print2file(PMU_OM_LOG,"pmu_hi6559:%s short !\n", reg_np_scp_record1_cont[j].cont);
         }
    }
    /* BUCK过流检查,0x19寄存器 */
    for (j = 0; j < HI6559_NP_OCP_RECORD1_CONT_NUM; j++)
    {
         if (a_ucRecordReg[1] & (u8)((u32)0x1 << reg_np_ocp_record1_cont[j].bit_ofs))  /*lint !e690,!e831*/
         {
            volt_need_off |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id);
            *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id);
            print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record1_cont[j].cont);
         }
    }
    
    /* LDO1~8过流检查,0x1A寄存器 */
    for (j = 0; j < HI6559_NP_OCP_RECORD2_CONT_NUM; j++)
    {
         if (a_ucRecordReg[2] & (u8)((u32)0x1 << reg_np_ocp_record2_cont[j].bit_ofs))  /*lint !e690,!e831*/
         {
            volt_need_off |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id);
            *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id);
            print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record2_cont[j].cont);
         }
    }    

    /* ldo9~14过流,寄存器0x1B */
    for (j = 0; j < HI6559_NP_OCP_RECORD3_CONT_NUM; j++)       
    {
         if (a_ucRecordReg[3] & (u8)((u32)0x1 << j))    /*lint !e690,!e831*/
         {
            volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j));
            *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j));
            print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO09 + j - 1);
         }
    }
    
    /* ldo22~24过流,寄存器0x1C */
    for(j = 0; j < HI6559_NP_OCP_RECORD4_CONT_NUM; j++)        
    {
         if (a_ucRecordReg[4] & (u8)((u32)0x1 << (j + 5)))    /*lint !e690,!e831*/
         {
            volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j));
            *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j));
            print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO22 + j + 6);
         }
    }
    
    /* lvs7过流,寄存器0x1D */
    if(a_ucRecordReg[5] & (u8)((u32)0x1 << HI6559_LVS07_BIT_OFFSET))    
    {
        volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS07);
        *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS07);
        print2file(PMU_OM_LOG,"pmu_hi6559:LVS7 overflow !\n");
    }
    
    /* lvs9过流,寄存器0x1E */
    if(a_ucRecordReg[6] & (u8)((u32)0x1 << HI6559_LVS09_BIT_OFFSET))         
    {
        volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS09);
        *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS09);
        print2file(PMU_OM_LOG,"pmu_hi6559:LVS09 overflow !\n");
    } 

    /* 异常信息发给C核 */
    if(volt_need_off)
    {
        ret = bsp_icc_send(ICC_CPU_MODEM, PA_RF_ICC_CHN_ID, (u8*)&volt_need_off, sizeof(u32));
        if(sizeof(u32) != (u32)ret)
        {
            pmic_print_error("bsp_icc_send failed, ret = %d!\n", ret);
        }
    }
    
    /* 根据NV值确认是否需要关闭过流的电源 */
    for(j = PMIC_HI6559_VOLT_MIN; j <= PMIC_HI6559_VOLT_MAX; j++)
    {
        if(pmu_exc_pro.ulOcpIsOff)
        {
            if(volt_need_off & ((u32)0x1 << j))
            {
                pmic_print_error("hi6559:volt id %d overflow !\n", j);

                /* 需要关闭过流的电压源,则关闭 */
                if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsOff)
                {
                    pmic_print_error("hi6559:volt id %d will be closed !\n", j);
                    bsp_hi6559_volt_disable(j);
                }

                /* 过流需要重启,则重启 */
                if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsRst)
                {
                    pmic_print_error("hi6559:system will be restart!\n");
                    system_error(DRV_ERRNO_PMU_OVER_CUR, PMU_STATE_OVER_CUR, j, (char *)&volt_need_off, (u32)sizeof(volt_need_off));
                }
            }
        }
        else
        {
            if(volt_need_off & ((u32)0x1 << j))
            {
                pmic_print_error("hi6559:volt id %d overflow !\n", j);
            }
        }
    }

    /*清除非下电中断状态寄存器*/
    for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++)
    {
        bsp_hi6559_reg_write((HI6559_NP_SCP_RECORD1_OFFSET + i), a_ucRecordReg[i]); /*lint !e661*/
    }

    return;/*lint !e438*/
}
示例#7
0
/*****************************************************************************
 函 数 名  : hi6559_om_wk_handler
 功能描述  : 将非下电状态记录寄存器写入log文件,并判断此次启动是否由PMU引起的重启
 输入参数  : 无
 输出参数  : 无
 返 回 值  : 无
 备注说明  : 无
*****************************************************************************/
void hi6559_om_wk_handler(void)
{
    s32 j = 0;

    /* 保存非下电寄存器值 */
    for(j = 0; j < HI6559_NP_RECORD_REG_NUM; j++)
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:np%d:%x!\n", j + 1, pmu_hi6559_om_boot[j]);
    }

    /* 欠压2.5V */
    if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_UNDER_2P5_OFFSET ) )    
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.5v last time!\n");
    }
    
    /* 欠压2.85/3.0V */
    if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_UNDER_2P85_OFFSET ) )   
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:vsys under 2.85/3.0v last time!\n");
    }    
    
    /* 过压6.0V */
    if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_VSYS_OVER_6P0_OFFSET ))      
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:vsys over 6.0v last time!\n");
    }    
    
    /* 过温125度 */
    if(pmu_hi6559_om_boot[0] & (0x01 << HI6559_OTMP_125_OFFSET))            
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:temperature over 125℃ last time!\n");
    }  
    
    /* 过温150度 */
    if(pmu_hi6559_om_boot[1] & (0x01 << HI6559_OTMP_150_OFFSET ) )          
    {
        print2file(PMU_OM_LOG,"pmu_hi6559:temperature over 150℃ last time!\n");
    }    
    
    /* buck短路,寄存器0x18 */
    for (j = 0; j < HI6559_NP_SCP_RECORD1_CONT_NUM; j++)       
    {
        if (pmu_hi6559_om_boot[3] & (u8)((u32)0x1 << reg_np_scp_record1_cont[j].bit_ofs))
        {
            print2file(PMU_OM_LOG,"pmu_hi6559: %s short last time!\n", reg_np_scp_record1_cont[j].cont);
        }
    }
    
    /* buck过流,寄存器0x19 */
    for (j = 0; j < HI6559_NP_OCP_RECORD1_CONT_NUM; j++)       
    {
        if (pmu_hi6559_om_boot[4] & (u8)((u32)0x1 << reg_np_ocp_record1_cont[j].bit_ofs))
        {
            print2file(PMU_OM_LOG,"pmu_hi6559: %s overflow last time!\n", reg_np_ocp_record1_cont[j].cont);
        }
    }
    
    /* ldo1~8过流,寄存器0x1A */
    for (j = 0; j < HI6559_NP_OCP_RECORD2_CONT_NUM; j++)       
    {
        if (pmu_hi6559_om_boot[5] & (u8)((u32)0x1 << reg_np_ocp_record2_cont[j].bit_ofs))
        {
            print2file(PMU_OM_LOG,"pmu_hi6559: %s overflow last time!\n", reg_np_ocp_record2_cont[j].cont);
        }
    }
    
    /* ldo9~14过流,寄存器0x1B */   
    for (j = 0; j < HI6559_NP_OCP_RECORD3_CONT_NUM; j++)       
    {
        if (pmu_hi6559_om_boot[6] & (u8)((u32)0x1 << j))
        {
            print2file(PMU_OM_LOG,"pmu_hi6559: LDO%d overflow last time!\n", j + 9);
        }
    }
    
    /* ldo22~24过流,寄存器0x1C */
    for(j = 0; j < HI6559_NP_OCP_RECORD4_CONT_NUM; j++)        
    {
        if (pmu_hi6559_om_boot[7] & (u8)((u32)0x1 << (j + 5)))
        {
            print2file(PMU_OM_LOG,"pmu_hi6559: LDO%d overflow last time!\n", j + 22);
        }
    }
    
    /* lvs7过流,寄存器0x1D */
    if (pmu_hi6559_om_boot[8] & (u8)((u32)0x1 << HI6559_LVS07_BIT_OFFSET))    
    {
        print2file(PMU_OM_LOG,"pmu_hi6559: LVS7 overflow last time!\n");
    }
    
    /* lvs9过流,寄存器0x1E */
    if (pmu_hi6559_om_boot[9] & (u8)((u32)0x1 << HI6559_LVS09_BIT_OFFSET))         
    {
        print2file(PMU_OM_LOG,"pmu_hi6559: LVS9 overflow last time!\n");
    }    

    return;
}
示例#8
0
int main(int argc, char *argv[]){
	if (argc != 3) {
    	printf("USAGE: %s <nx> <nthreads>\n", argv[0]);
    	exit(1);
    }

    double start_time = omp_get_wtime();
    const int nx = atoi(argv[1]);
    const int nthreads = atoi(argv[2]);
    const double pi = acos(0)*2;
    const double delta = 0.25;
    const int n = 2*nx*nx;
    const double dx = pi/nx;
    double v_sum = 0;
    int t, i, j;
    int chunk;
    chunk = 128/4;


    string file = argv[0];
    file.append(argv[1]);
    file.append("_output");
    double ** T_c = new_Temperature(nx, dx);
    double ** T_p = new_Temperature(nx, dx);



    omp_set_num_threads(nthreads);
    #pragma omp parallel default(none) shared(T_c, T_p) private(i, j, t)
    for(t = 0; t < n; t++){ 
        #pragma omp for nowait 
    	for(i = 0; i < nx; i++){
            for(j = 1; j < nx-1; j++){
                if(i == 0){
                    T_c[i][j] = delta*(T_p[nx-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]);
                }
                else if(i == nx -1){
                    T_c[i][j] = delta*(T_p[i-1][j] +T_p[0][j]+T_p[i][j-1]+T_p[i][j+1]);
                }
                else{
                    T_c[i][j] = delta*(T_p[i-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]);
                }
            }
        }

        #pragma omp barrier

        #pragma omp for nowait
    	for(int i = 0; i < nx; i ++){
            for(int j = 0; j < nx; j++){
                T_p[i][j] = T_c[i][j];
            }
        }  
    }


    double stop_time = omp_get_wtime();

	print2file(T_c, nx, file);
    for(int i = 0; i < nx; i ++){
        for(int j = 0; j < nx; j++){
            v_sum += T_c[i][j];
        }
    }

    for(int i = 0; i < nx; i ++){
        delete [] T_c[i];
        delete [] T_p[i];
    }
    delete [] T_c;
    delete [] T_p;

    cout << "Volume average for "<<nx<<" x "<<nx<<" "<<v_sum/nx/nx<<endl;
    cout << "Running time is: " << stop_time - start_time << "s" << endl;
    return 0;
}
示例#9
0
int main(int argc, char *argv[]){
    if (argc != 2) {
        printf("USAGE: %s <nx>\n", argv[0]);
        exit(1);
    }

    const int nx = atoi(argv[1]);
    const double pi = acos(0)*2;
    const double delta = 0.25;
    const int n = 2*nx*nx;
    const double dx = pi/nx;
    double ** T_c;
    double ** T_p;
    


    string file = argv[0];
    file.append(argv[1]);
    file.append("_output");


    int tag = 123;
    int n_tsk, rank;
    double time_start =  MPI_Wtime(); 
    MPI_Status status;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD, &n_tsk);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    int interval = nx/n_tsk;
    /**** Create send and receive ***/

    double send_bound1[nx];
    double send_bound2[nx];
    double receive_bound1[nx];
    double receive_bound2[nx];

    /****** Create new segment ******/
    T_c = new double* [interval + 2];
    T_p = new double* [interval + 2];

    for(int i = 0; i < interval + 2; i++){
        T_c[i] = new  double[nx];
        T_p[i] = new  double[nx];
    }

    /****** Initialize array ********/
    for(int i = 0; i < interval + 2; i++){
        for(int j = 1; j < nx-1; j ++){
            T_c[i][j] = 0;
            T_p[i][j] = 0;
        }
    }
    for(int i = 0; i < interval + 2; i++){
        T_p[i][0] = pow(cos(dx*(rank*interval-1+i)), 2);        
        T_p[i][nx-1] = pow(sin(dx*(rank*interval-1+i)), 2);
        T_c[i][0] = T_p[i][0];
        T_c[i][nx-1] = T_p[i][nx-1];
    }

    for(int t = 0; t < n; t ++){
        for(int i = 1; i < interval+1; i++){
            for(int j = 1; j < nx-1; j++){
                T_c[i][j] = delta*(T_p[i-1][j] +T_p[i+1][j]+T_p[i][j-1]+T_p[i][j+1]);                
            }
        }
	for(int i = 1; i < interval+1; i++){
	    for(int j = 1; j < nx-1; j++){
               T_p[i][j] =  T_c[i][j];
            }
	}
        /*** Initial message ******/
        for(int i = 0; i < nx; i++){
            send_bound1[i] = T_c[1][i];
            send_bound2[i] = T_c[interval][i];
        
	}
        if (rank != 0){
	     MPI_Recv(&receive_bound2, nx, MPI_DOUBLE, rank-1, tag+1, MPI_COMM_WORLD, &status);
	}
	MPI_Send(&send_bound2, nx, MPI_DOUBLE, (rank+1)%n_tsk, tag+1, MPI_COMM_WORLD);
	if (rank == 0){
	      MPI_Recv(&receive_bound2, nx, MPI_DOUBLE, n_tsk-1, tag+1, MPI_COMM_WORLD, &status);
	}	
	if (rank != n_tsk -1){
             MPI_Recv(&receive_bound1, nx, MPI_DOUBLE, rank+1, tag, MPI_COMM_WORLD, &status);
        }		
	MPI_Send(&send_bound1, nx, MPI_DOUBLE, ((rank-1)%n_tsk+n_tsk)%n_tsk, tag, MPI_COMM_WORLD);	
	if (rank == n_tsk-1){
	      MPI_Recv(&receive_bound1, nx, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &status);
	}
        for(int i = 0; i < nx; i++){
            T_p[0][i] = receive_bound2[i];
            T_p[interval+1][i] = receive_bound1[i];
        }
    }
    
    if(rank != 0){
        double send_T[nx*interval];    
        for(int i = 0; i < interval; i++){      
            for(int j = 0; j < nx; j ++){
                send_T[i*nx+j] = T_c[i+1][j];
            }
        }
        MPI_Send(&send_T, nx*interval, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD);

    }
    else{
        double receive_T[nx*interval];
        double ** T = new double*[nx];
        double v_sum = 0;
        for(int i = 0; i < nx; i++){
            T[i] = new double [nx];
        }
        for(int i = 1; i < interval + 1; i++){
            for(int j = 0; j < nx; j ++){
                T[i-1][j] = T_c[i][j];
                v_sum += T_c[i][j];
            }
        }
        for(int i = 1; i < n_tsk; i++){
            MPI_Recv(&receive_T, nx*interval, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &status);
            for(int j = 0; j < interval; j++){      
                for(int k = 0; k < nx; k ++){
                    T[i*interval+j][k] = receive_T[j*nx+k];
                    v_sum += receive_T[j*nx+k];
                }
            }
        }
        double time_end =  MPI_Wtime();
        cout << "Volume average for "<<nx<<" x "<<nx<<" "<<v_sum/nx/nx<<endl;
        cout <<"Running time is "<<time_end-time_start<< "s" <<endl;
        print2file(T, nx, file);
        for(int i = 0; i < nx; i++){
	    delete [] T[i];
	}
	delete [] T;
    }
    for(int i = 0; i < interval + 2; i++){
        delete [] T_c[i];
        delete [] T_p[i];
    }
    delete [] T_c;
    delete [] T_p;

    MPI_Finalize();  
}