⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hypre-struct_overlap_innerprod.c

📁 利用C
💻 C
字号:
/*BHEADER********************************************************************** * Copyright (c) 2006   The Regents of the University of California. * Produced at the Lawrence Livermore National Laboratory. * Written by the HYPRE team. UCRL-CODE-222953. * All rights reserved. * * This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/). * Please see the COPYRIGHT_and_LICENSE file for the copyright notice,  * disclaimer, contact information and the GNU Lesser General Public License. * * HYPRE 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) version 2.1 dated February 1999. * * HYPRE 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 terms and conditions of the GNU General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Revision: 2.7 $ ***********************************************************************EHEADER*//****************************************************************************** * * Structured inner product routine for overlapped grids. Computes the * inner product of two vectors over an overlapped grid. * *****************************************************************************/#include "headers.h"/* this is all commented out now as it is currently not used - if used   in the future, it needs to use the box manager instead of the neighbors    structure *//*-------------------------------------------------------------------------- * hypre_StructOverlapInnerProd *--------------------------------------------------------------------------*/#ifdef HYPRE_USE_PTHREADSdouble          *local_result_ref[hypre_MAX_THREADS];#endifdouble           final_overlapinnerprod_result;doublehypre_StructOverlapInnerProd( hypre_StructVector *x,                              hypre_StructVector *y ){   double               local_result, overlap_result;   double               process_result;                      hypre_Box           *x_data_box;   hypre_Box           *y_data_box;   hypre_BoxArray      *overlap_boxes;                      int                  xi;   int                  yi;                      double              *xp;   double              *yp;                      hypre_BoxArray      *boxes;   hypre_Box           *boxi, *boxj, intersect_box;   hypre_StructGrid    *grid= hypre_StructVectorGrid(y);   hypre_BoxManager    *boxman = hypre_StructGridBoxMan(grid);   hypre_BoxArray      *neighbor_boxes;   int                 *neighbors_procs= NULL;   hypre_BoxArray      *selected_nboxes;   hypre_BoxArray      *tmp_box_array, *tmp2_box_array;   hypre_Index          loop_size;   hypre_IndexRef       start;   hypre_Index          unit_stride;                      int                  i, j;   int                  myid;   int                  boxarray_size;   int                  loopi, loopj, loopk;#ifdef HYPRE_USE_PTHREADS   int                  threadid = hypre_GetThreadID();#endif      local_result = 0.0;   process_result = 0.0;   hypre_SetIndex(unit_stride, 1, 1, 1);   MPI_Comm_rank(hypre_StructVectorComm(y), &myid);   /*-----------------------------------------------------------------------    * Determine the overlapped boxes on this local processor.    *-----------------------------------------------------------------------*/   boxes        = hypre_StructGridBoxes(hypre_StructVectorGrid(y));   boxarray_size= hypre_BoxArraySize(boxes);   /*-----------------------------------------------------------------------    * To compute the inner product over this local processor, given a box,     * the inner product between x & y is computed over the whole box and    * over any overlapping between this box and overlap_boxes. The latter    * result is subtracted from the former. Overlapping between more than    * two boxes are handled.    *-----------------------------------------------------------------------*/   hypre_ForBoxI(i, boxes)   {      boxi  = hypre_BoxArrayBox(boxes, i);      start = hypre_BoxIMin(boxi);      x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);      y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);      xp = hypre_StructVectorBoxData(x, i);      yp = hypre_StructVectorBoxData(y, i);      hypre_BoxGetSize(boxi, loop_size);#ifdef HYPRE_USE_PTHREADS   local_result_ref[threadid] = &local_result;#endif      hypre_BoxLoop2Begin(loop_size,                          x_data_box, start, unit_stride, xi,                          y_data_box, start, unit_stride, yi);#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,xi,yi#define HYPRE_SMP_REDUCTION_OP +#define HYPRE_SMP_REDUCTION_VARS local_result#include "hypre_box_smp_forloop.h"      hypre_BoxLoop2For(loopi, loopj, loopk, xi, yi)      {          local_result += xp[xi] * yp[yi];      }      hypre_BoxLoop2End(xi, yi);      /*--------------------------------------------------------------------       * intersect all boxes from (i+1) to boxarray_size        *--------------------------------------------------------------------*/      overlap_boxes= hypre_BoxArrayCreate(0);      for (j= (i+1); j< boxarray_size; j++)      {         boxj= hypre_BoxArrayBox(boxes, j);         hypre_IntersectBoxes(boxi, boxj, &intersect_box);         if (hypre_BoxVolume(&intersect_box))         {             hypre_AppendBox(&intersect_box, overlap_boxes);         }      }      if (hypre_BoxArraySize(overlap_boxes) > 1)      {         hypre_UnionBoxes(overlap_boxes);      }      /*--------------------------------------------------------------------       * compute inner product over overlap         *--------------------------------------------------------------------*/      if (hypre_BoxArraySize(overlap_boxes))      {         overlap_result= 0.0;         hypre_ForBoxI(j, overlap_boxes)         {            boxj  = hypre_BoxArrayBox(overlap_boxes, j);            start = hypre_BoxIMin(boxj);            hypre_BoxGetSize(boxj, loop_size);            hypre_BoxLoop2Begin(loop_size,                                x_data_box, start, unit_stride, xi,                                y_data_box, start, unit_stride, yi);#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,xi,yi#include "hypre_box_smp_forloop.h"            hypre_BoxLoop2For(loopi, loopj, loopk, xi, yi)            {               overlap_result += xp[xi] * yp[yi];            }            hypre_BoxLoop2End(xi, yi);         }         local_result-= overlap_result;      }      hypre_BoxArrayDestroy(overlap_boxes);   }   /*-----------------------------------------------------------------------    * Determine the across processor overlap. The inner product is computed    * and subtracted on processors that share the overlap except the one    * with the lowest processor id. Therefore, on this processor, we need     * to subtract only overlaps with boxes on processors with id < myid.    *-----------------------------------------------------------------------*/   neighbor_boxes = hypre_BoxArrayCreate(0);   hypre_BoxManGetAllEntriesBoxesProc(boxman, neighbor_boxes, neighbors_procs);      selected_nboxes= hypre_BoxArrayCreate(0);   /* extract only boxes on processors with ids < myid. */   hypre_ForBoxI(i, boxes)   {      if (neighbors_procs[i] < myid)      {         hypre_AppendBox(hypre_BoxArrayBox(neighbor_boxes, i), selected_nboxes);      }   }   hypre_BoxArrayDestroy(neighbor_boxes);   boxes= hypre_StructGridBoxes(hypre_StructVectorGrid(y));   overlap_boxes= hypre_BoxArrayCreate(0);   hypre_ForBoxI(i, boxes)   {      boxi= hypre_BoxArrayBox(boxes, i);      hypre_ForBoxI(j, selected_nboxes)      {         boxj= hypre_BoxArrayBox(selected_nboxes, j);            hypre_IntersectBoxes(boxi, boxj, &intersect_box);         if (hypre_BoxVolume(&intersect_box))         {             hypre_AppendBox(&intersect_box, overlap_boxes);         }      }   }   hypre_BoxArrayDestroy(selected_nboxes);   /*-----------------------------------------------------------------------    * Union the overlap_boxes and then begin to compute and subtract chunks     * and norms.    *-----------------------------------------------------------------------*/   if (hypre_BoxArraySize(overlap_boxes) > 1)   {      hypre_UnionBoxes(overlap_boxes);   }   if (hypre_BoxArraySize(overlap_boxes))   {      overlap_result= 0.0;      hypre_ForBoxI(i, boxes)      {         boxi  = hypre_BoxArrayBox(boxes, i);         x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);         y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);         xp = hypre_StructVectorBoxData(x, i);         yp = hypre_StructVectorBoxData(y, i);         tmp_box_array= hypre_BoxArrayCreate(0);         hypre_ForBoxI(j, overlap_boxes)         {            boxj= hypre_BoxArrayBox(overlap_boxes, j);            hypre_IntersectBoxes(boxi, boxj, &intersect_box);            if (hypre_BoxVolume(&intersect_box))            {               start= hypre_BoxIMin(&intersect_box);               hypre_BoxGetSize(&intersect_box, loop_size);               hypre_BoxLoop2Begin(loop_size,                                   x_data_box, start, unit_stride, xi,                                   y_data_box, start, unit_stride, yi);#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,xi,yi#include "hypre_box_smp_forloop.h"               hypre_BoxLoop2For(loopi, loopj, loopk, xi, yi)               {                  overlap_result += xp[xi] * yp[yi];               }               hypre_BoxLoop2End(xi, yi);               hypre_AppendBox(&intersect_box, tmp_box_array);            }  /* if (hypre_BoxVolume(&intersect_box)) */         }     /* hypre_ForBoxI(j, overlap_boxes) */         /*-------------------------------------------------------------------------          * Subtract the intersection boxes so that norm on higher degree overlaps          * on this processor are computed only once.          *-------------------------------------------------------------------------*/         tmp2_box_array= hypre_BoxArrayCreate(0);         hypre_SubtractBoxArrays(overlap_boxes, tmp_box_array, tmp2_box_array);         hypre_BoxArrayDestroy(tmp_box_array);         hypre_BoxArrayDestroy(tmp2_box_array);      }  /* hypre_ForBoxI(i, boxes) */      local_result-= overlap_result;   }  /* if (hypre_BoxArraySize(overlap_boxes)) */   hypre_BoxArrayDestroy(overlap_boxes);#ifdef HYPRE_USE_PTHREADS   if (threadid != hypre_NumThreads)   {      for (i = 0; i < hypre_NumThreads; i++)         process_result += *local_result_ref[i];   }   else      process_result = *local_result_ref[threadid];#else   process_result = local_result;#endif   MPI_Allreduce(&process_result, &final_overlapinnerprod_result, 1,                 MPI_DOUBLE, MPI_SUM, hypre_StructVectorComm(x));#ifdef HYPRE_USE_PTHREADS   if (threadid == 0 || threadid == hypre_NumThreads)#endif   hypre_IncFLOPCount(2*hypre_StructVectorGlobalSize(x));   return final_overlapinnerprod_result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -