Пример #1
0
SubgridArray  *GetGridSubgrids(
   SubgridArray  *all_subgrids)
{
   SubgridArray  *subgrids;

   Subgrid       *s;

   int            i, my_proc;


   my_proc   = amps_Rank(amps_CommWorld);

   subgrids = NewSubgridArray();

   ForSubgridI(i, all_subgrids)
   {
      s = SubgridArraySubgrid(all_subgrids, i);
      if (SubgridProcess(s) == my_proc)
	 AppendSubgrid(s, subgrids);
   }
Пример #2
0
void BCInternal(
                Problem *    problem,
                ProblemData *problem_data,
                Matrix *     A,
                Vector *     f,
                double       time)
{
  PFModule      *this_module = ThisPFModule;
  PublicXtra    *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);

  PFModule      *phase_density = ProblemPhaseDensity(problem);

  WellData         *well_data = ProblemDataWellData(problem_data);
  WellDataPhysical *well_data_physical;
  WellDataValue    *well_data_value;

  TimeCycleData    *time_cycle_data;

  int num_conditions = (public_xtra->num_conditions);

  Type0            *dummy0;

  Grid             *grid = VectorGrid(f);

  SubgridArray     *internal_bc_subgrids;

  Subgrid          *subgrid, *ibc_subgrid, *well_subgrid, *new_subgrid;

  Submatrix        *A_sub;
  Subvector        *f_sub;

  double           *internal_bc_conditions, *mp;

  double Z;

  double dx, dy, dz;
  int ix, iy, iz;
  int nx, ny, nz;
  int rx, ry, rz;
  int process;

  int i, j, k, i_sft, j_sft, k_sft;
  int grid_index, ibc_sg, well, index;
  int cycle_number, interval_number;

  double dtmp, ptmp, head, phead;

  int stencil[7][3] = { { 0, 0, 0 },
                        { -1, 0, 0 },
                        { 1, 0, 0 },
                        { 0, -1, 0 },
                        { 0, 1, 0 },
                        { 0, 0, -1 },
                        { 0, 0, 1 } };

  /***** Some constants for the routine *****/

  /* Hard-coded assumption for constant density. */
  PFModuleInvokeType(PhaseDensityInvoke, phase_density, (0, NULL, NULL, &ptmp, &dtmp, CALCFCN));
  dtmp = ProblemGravity(problem) * dtmp;

  /*--------------------------------------------------------------------
   * gridify the internal boundary locations (should be done elsewhere?)
   *--------------------------------------------------------------------*/

  if (num_conditions > 0)
  {
    internal_bc_subgrids = NewSubgridArray();
    internal_bc_conditions = ctalloc(double, num_conditions);

    for (i = 0; i < num_conditions; i++)
    {
      switch ((public_xtra->type[i]))
      {
        case 0:
        {
          dummy0 = (Type0*)(public_xtra->data[i]);

          ix = IndexSpaceX((dummy0->xlocation), 0);
          iy = IndexSpaceY((dummy0->ylocation), 0);
          iz = IndexSpaceZ((dummy0->zlocation), 0);

          nx = 1;
          ny = 1;
          nz = 1;

          rx = 0;
          ry = 0;
          rz = 0;

          process = amps_Rank(amps_CommWorld);

          new_subgrid = NewSubgrid(ix, iy, iz,
                                   nx, ny, nz,
                                   rx, ry, rz,
                                   process);

          AppendSubgrid(new_subgrid, internal_bc_subgrids);

          internal_bc_conditions[i] = (dummy0->value);

          break;
        }
      }
    }
  }
Пример #3
0
/**
 *
 * \Ref{amps_SFBCast} is used to read data from a shared file.  Note
 * that the input is described by an \Ref{amps_Invoice} rather than the
 * standard {\bf printf} syntax.  This is to allow a closer mapping to
 * the communication routines.  Due to this change be careful; items in
 * the input file must match what is in the invoice description.  As it's
 * name implies this function reads from a file and broadcasts the data
 * in the file to all the nodes who are in the {\bf comm} context.  Think
 * of it as doing an \Ref{amps_BCAST} with a file replacing the node as
 * the source.  The data is stored in ASCII format and read in using
 * the Standard C library function {\bf scanf} so it's formatting rules
 * apply.
 *
 * {\large Example:}
 * \begin{verbatim}
 * amps_File file;
 * amps_Invoice invoice;
 *
 * file = amps_SFopen(filename, "r");
 *
 * amps_SFBCast(amps_CommWorld, file, invoice);
 *
 * amps_SFclose(file);
 * \end{verbatim}
 *
 * {\large Notes:}
 *
 * @memo Broadcast from a shared file
 * @param comm Communication context [IN]
 * @param file Shared file handle [IN]
 * @param invoice Descriptions of data to read from file and distribute [IN/OUT]
 * @return Error code
 */
int amps_SFBCast(amps_Comm comm, amps_File file, amps_Invoice invoice)
{
  amps_InvoiceEntry *ptr;
  int stride, len;
  int malloced = 0;

  if (!amps_Rank(comm))
  {
    amps_ClearInvoice(invoice);

    invoice->combuf_flags |= AMPS_INVOICE_NON_OVERLAYED;

    invoice->comm = comm;

    /* for each entry in the invoice read the value from the input file */
    ptr = invoice->list;
    while (ptr != NULL)
    {
      /* invoke the packing convert out for the entry */
      /* if user then call user ones */
      /* else switch on builtin type */
      if (ptr->len_type == AMPS_INVOICE_POINTER)
        len = *(ptr->ptr_len);
      else
        len = ptr->len;

      if (ptr->stride_type == AMPS_INVOICE_POINTER)
        stride = *(ptr->ptr_stride);
      else
        stride = ptr->stride;

      switch (ptr->type)
      {
        case AMPS_INVOICE_CHAR_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(char) * (size_t)(len * stride));
            amps_ScanChar(file, *( char**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanChar(file, (char*)ptr->data, len, stride);
          break;

        case AMPS_INVOICE_SHORT_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(short) * (size_t)(len * stride));
            amps_ScanShort(file, *( short**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanShort(file, (short*)ptr->data, len, stride);

          break;

        case AMPS_INVOICE_INT_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(int) * (size_t)(len * stride));
            amps_ScanInt(file, *( int**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanInt(file, (int*)ptr->data, len, stride);

          break;

        case AMPS_INVOICE_LONG_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(long) * (size_t)(len * stride));
            amps_ScanLong(file, *( long**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanLong(file, (long*)ptr->data, len, stride);

          break;

        case AMPS_INVOICE_FLOAT_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(float) * (size_t)(len * stride));
            amps_ScanFloat(file, *( float**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanFloat(file, (float*)ptr->data, len, stride);

          break;

        case AMPS_INVOICE_DOUBLE_CTYPE:
          if (ptr->data_type == AMPS_INVOICE_POINTER)
          {
            *((void**)(ptr->data)) = (void*)malloc(sizeof(double) * (size_t)(len * stride));
            amps_ScanDouble(file, *( double**)(ptr->data), len, stride);
            malloced = TRUE;
          }
          else
            amps_ScanDouble(file, (double*)ptr->data, len, stride);

          break;
      }
      ptr = ptr->next;
    }
  }

  return amps_BCast(comm, 0, invoice);
}
void RichardsBCInternal(
Problem     *problem,
ProblemData *problem_data,
Vector      *f,
Matrix      *A,
double       time,
Vector      *pressure,
int          fcn)
{
   PFModule      *this_module    = ThisPFModule;
   PublicXtra    *public_xtra    = (PublicXtra *)PFModulePublicXtra(this_module);

   WellData         *well_data = ProblemDataWellData(problem_data);
   WellDataPhysical *well_data_physical;
   WellDataValue    *well_data_value;

   TimeCycleData    *time_cycle_data;

   int               num_conditions = (public_xtra -> num_conditions);
   int               num_wells, total_num;

   Type0            *dummy0;

   Grid             *grid = VectorGrid(pressure);

   SubgridArray     *internal_bc_subgrids = NULL;

   Subgrid          *subgrid, *subgrid_ind, *new_subgrid;

   Subvector        *p_sub;


   double           *pp;
   double           *internal_bc_conditions = NULL;

   double            dx, dy, dz;
   double            value;

   int               ix, iy, iz;
   int               nx, ny, nz;
   int               rx, ry, rz;
   int               process;

   int               i, j, k;
   int               grid_index, well, index;
   int               cycle_number, interval_number;
   int               ip, im;

   /*--------------------------------------------------------------------
    * gridify the internal boundary locations (should be done elsewhere?)
    *--------------------------------------------------------------------*/

   if ( num_conditions > 0 )
   {

      internal_bc_subgrids = NewSubgridArray();
      internal_bc_conditions = ctalloc(double, num_conditions);

      for (i = 0; i < num_conditions;i++)
      {
         switch((public_xtra -> type[i]))
         {

         case 0:
         {
            dummy0 = (Type0 *)(public_xtra -> data[i]);

            ix = IndexSpaceX((dummy0 -> xlocation), 0);
            iy = IndexSpaceY((dummy0 -> ylocation), 0);
            iz = IndexSpaceZ((dummy0 -> zlocation), 0);

            nx = 1;
            ny = 1;
            nz = 1;

            rx = 0;
            ry = 0;
            rz = 0;

            process = amps_Rank(amps_CommWorld);

            new_subgrid = NewSubgrid(ix, iy, iz,
                                     nx, ny, nz,
                                     rx, ry, rz,
                                     process);

            AppendSubgrid(new_subgrid, internal_bc_subgrids);

            internal_bc_conditions[i] = (dummy0 -> value);

            break;
         }
         }
      }
   }
Пример #5
0
PFModule  *KinsolNonlinSolverInitInstanceXtra(
                                              Problem *    problem,
                                              Grid *       grid,
                                              ProblemData *problem_data,
                                              double *     temp_data)
{
  PFModule      *this_module = ThisPFModule;
  PublicXtra    *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);
  InstanceXtra  *instance_xtra;

  int neq = public_xtra->neq;
  int max_restarts = public_xtra->max_restarts;
  int krylov_dimension = public_xtra->krylov_dimension;
  int max_iter = public_xtra->max_iter;
  int print_flag = public_xtra->print_flag;
  int eta_choice = public_xtra->eta_choice;

  long int     *iopt;
  double       *ropt;

  double eta_value = public_xtra->eta_value;
  double eta_alpha = public_xtra->eta_alpha;
  double eta_gamma = public_xtra->eta_gamma;
  double derivative_epsilon = public_xtra->derivative_epsilon;

  Vector       *fscale;
  Vector       *uscale;

  State        *current_state;

  KINSpgmruserAtimesFn matvec = public_xtra->matvec;
  KINSpgmrPrecondFn pcinit = public_xtra->pcinit;
  KINSpgmrPrecondSolveFn pcsolve = public_xtra->pcsolve;

  KINMem kin_mem;
  FILE                  *kinsol_file;
  char filename[255];

  int i;

  if (PFModuleInstanceXtra(this_module) == NULL)
    instance_xtra = ctalloc(InstanceXtra, 1);
  else
    instance_xtra = (InstanceXtra*)PFModuleInstanceXtra(this_module);

  /*-----------------------------------------------------------------------
   * Initialize module instances
   *-----------------------------------------------------------------------*/

  if (PFModuleInstanceXtra(this_module) == NULL)
  {
    if (public_xtra->precond != NULL)
      instance_xtra->precond =
        PFModuleNewInstanceType(KinsolPCInitInstanceXtraInvoke, public_xtra->precond,
                                (problem, grid, problem_data, temp_data,
                                 NULL, NULL, NULL, 0, 0));
    else
      instance_xtra->precond = NULL;

    instance_xtra->nl_function_eval =
      PFModuleNewInstanceType(NlFunctionEvalInitInstanceXtraInvoke, public_xtra->nl_function_eval,
                              (problem, grid, temp_data));

    if (public_xtra->richards_jacobian_eval != NULL)
      /* Initialize instance for nonsymmetric matrix */
      instance_xtra->richards_jacobian_eval =
        PFModuleNewInstanceType(RichardsJacobianEvalInitInstanceXtraInvoke, public_xtra->richards_jacobian_eval,
                                (problem, grid, problem_data, temp_data, 0));
    else
      instance_xtra->richards_jacobian_eval = NULL;
  }
  else
  {
    if (instance_xtra->precond != NULL)
      PFModuleReNewInstanceType(KinsolPCInitInstanceXtraInvoke,
                                instance_xtra->precond,
                                (problem, grid, problem_data, temp_data,
                                 NULL, NULL, NULL, 0, 0));

    PFModuleReNewInstanceType(NlFunctionEvalInitInstanceXtraInvoke, instance_xtra->nl_function_eval,
                              (problem, grid, temp_data));

    if (instance_xtra->richards_jacobian_eval != NULL)
      PFModuleReNewInstanceType(RichardsJacobianEvalInitInstanceXtraInvoke, instance_xtra->richards_jacobian_eval,
                                (problem, grid, problem_data, temp_data, 0));
  }

  /*-----------------------------------------------------------------------
   * Initialize KINSol input parameters and memory instance
   *-----------------------------------------------------------------------*/

  if (PFModuleInstanceXtra(this_module) == NULL)
  {
    current_state = ctalloc(State, 1);

    /* Set up the grid data for the kinsol stuff */
    SetPf2KinsolData(grid, 1);

    /* Initialize KINSol parameters */
    sprintf(filename, "%s.%s", GlobalsOutFileName, "kinsol.log");
    if (!amps_Rank(amps_CommWorld))
      kinsol_file = fopen(filename, "w");
    else
      kinsol_file = NULL;
    instance_xtra->kinsol_file = kinsol_file;

    /* Initialize KINSol memory */
    kin_mem = (KINMem)KINMalloc(neq, kinsol_file, NULL);

    /* Initialize the gmres linear solver in KINSol */
    KINSpgmr((void*)kin_mem,           /* Memory allocated above */
             krylov_dimension,         /* Max. Krylov dimension */
             max_restarts,             /* Max. no. of restarts - 0 is none */
             1,                        /* Max. calls to PC Solve w/o PC Set */
             pcinit,                   /* PC Set function */
             pcsolve,                  /* PC Solve function */
             matvec,                   /* ATimes routine */
             current_state             /* User data for PC stuff */
             );

    /* Initialize optional arguments for KINSol */
    iopt = instance_xtra->int_optional_input;
    ropt = instance_xtra->real_optional_input;

    // Only print on rank 0
    iopt[PRINTFL] = amps_Rank(amps_CommWorld) ? 0 : print_flag;
    iopt[MXITER] = max_iter;
    iopt[PRECOND_NO_INIT] = 0;
    iopt[NNI] = 0;
    iopt[NFE] = 0;
    iopt[NBCF] = 0;
    iopt[NBKTRK] = 0;
    iopt[ETACHOICE] = eta_choice;
    iopt[NO_MIN_EPS] = 0;

    ropt[MXNEWTSTEP] = 0.0;
    ropt[RELFUNC] = derivative_epsilon;
    ropt[RELU] = 0.0;
    ropt[FNORM] = 0.0;
    ropt[STEPL] = 0.0;
    ropt[ETACONST] = eta_value;
    ropt[ETAALPHA] = eta_alpha;
    /* Put in conditional assignment of eta_gamma since KINSOL aliases */
    /* ETAGAMMA and ETACONST */
    if (eta_value == 0.0)
      ropt[ETAGAMMA] = eta_gamma;

    /* Initialize iteration counts */
    for (i = 0; i < OPT_SIZE; i++)
      instance_xtra->integer_outputs[i] = 0;

    /* Scaling vectors*/
    uscale = NewVectorType(grid, 1, 1, vector_cell_centered);
    InitVectorAll(uscale, 1.0);
    instance_xtra->uscale = uscale;

    fscale = NewVectorType(grid, 1, 1, vector_cell_centered);
    InitVectorAll(fscale, 1.0);
    instance_xtra->fscale = fscale;

    instance_xtra->feval = KINSolFunctionEval;
    instance_xtra->kin_mem = kin_mem;
    instance_xtra->current_state = current_state;
  }


  PFModuleInstanceXtra(this_module) = instance_xtra;
  return this_module;
}
Пример #6
0
int KinsolNonlinSolver(Vector *pressure, Vector *density, Vector *old_density, Vector *saturation, Vector *old_saturation, double t, double dt, ProblemData *problem_data, Vector *old_pressure, Vector *evap_trans, Vector *ovrl_bc_flx, Vector *x_velocity, Vector *y_velocity, Vector *z_velocity)
{
  PFModule     *this_module = ThisPFModule;
  PublicXtra   *public_xtra = (PublicXtra*)PFModulePublicXtra(this_module);
  InstanceXtra *instance_xtra = (InstanceXtra*)PFModuleInstanceXtra(this_module);

  Matrix       *jacobian_matrix = (instance_xtra->jacobian_matrix);
  Matrix       *jacobian_matrix_C = (instance_xtra->jacobian_matrix_C);

  Vector       *uscale = (instance_xtra->uscale);
  Vector       *fscale = (instance_xtra->fscale);

  PFModule  *nl_function_eval = instance_xtra->nl_function_eval;
  PFModule  *richards_jacobian_eval = instance_xtra->richards_jacobian_eval;
  PFModule  *precond = instance_xtra->precond;

  State        *current_state = (instance_xtra->current_state);

  int globalization = (public_xtra->globalization);
  int neq = (public_xtra->neq);

  double residual_tol = (public_xtra->residual_tol);
  double step_tol = (public_xtra->step_tol);

  SysFn feval = (instance_xtra->feval);
  KINMem kin_mem = (instance_xtra->kin_mem);
  FILE         *kinsol_file = (instance_xtra->kinsol_file);

  long int     *integer_outputs = (instance_xtra->integer_outputs);
  long int     *iopt = (instance_xtra->int_optional_input);
  double       *ropt = (instance_xtra->real_optional_input);

  int ret = 0;

  StateFunc(current_state) = nl_function_eval;
  StateProblemData(current_state) = problem_data;
  StateTime(current_state) = t;
  StateDt(current_state) = dt;
  StateOldDensity(current_state) = old_density;
  StateOldPressure(current_state) = old_pressure;
  StateOldSaturation(current_state) = old_saturation;
  StateDensity(current_state) = density;
  StateSaturation(current_state) = saturation;
  StateJacEval(current_state) = richards_jacobian_eval;
  StateJac(current_state) = jacobian_matrix;
  StateJacC(current_state) = jacobian_matrix_C;           //dok
  StatePrecond(current_state) = precond;
  StateEvapTrans(current_state) = evap_trans;       /*sk*/
  StateOvrlBcFlx(current_state) = ovrl_bc_flx;      /*sk*/
  StateXvel(current_state) = x_velocity;           //jjb
  StateYvel(current_state) = y_velocity;           //jjb
  StateZvel(current_state) = z_velocity;           //jjb

  if (!amps_Rank(amps_CommWorld))
    fprintf(kinsol_file, "\nKINSOL starting step for time %f\n", t);

  BeginTiming(public_xtra->time_index);

  ret = KINSol((void*)kin_mem,          /* Memory allocated above */
               neq,                     /* Dummy variable here */
               pressure,                /* Initial guess @ this was "pressure before" */
               feval,                   /* Nonlinear function */
               globalization,           /* Globalization method */
               uscale,                  /* Scalings for the variable */
               fscale,                  /* Scalings for the function */
               residual_tol,            /* Stopping tolerance on func */
               step_tol,                /* Stop tol. for sucessive steps */
               NULL,                    /* Constraints */
               TRUE,                    /* Optional inputs */
               iopt,                    /* Opt. integer inputs */
               ropt,                    /* Opt. double inputs */
               current_state            /* User-supplied input */
               );

  EndTiming(public_xtra->time_index);

  integer_outputs[NNI] += iopt[NNI];
  integer_outputs[NFE] += iopt[NFE];
  integer_outputs[NBCF] += iopt[NBCF];
  integer_outputs[NBKTRK] += iopt[NBKTRK];
  integer_outputs[SPGMR_NLI] += iopt[SPGMR_NLI];
  integer_outputs[SPGMR_NPE] += iopt[SPGMR_NPE];
  integer_outputs[SPGMR_NPS] += iopt[SPGMR_NPS];
  integer_outputs[SPGMR_NCFL] += iopt[SPGMR_NCFL];

  if (!amps_Rank(amps_CommWorld))
    PrintFinalStats(kinsol_file, iopt, integer_outputs);

  if (ret == KINSOL_SUCCESS || ret == KINSOL_INITIAL_GUESS_OK)
  {
    ret = 0;
  }

  return(ret);
}