コード例 #1
0
void 
extract_nodal_eb_vec(double sol_vec[], int var_no, int ktype, int matIndex,
		     int eb_index, double nodal_vec[], Exo_DB *exo, 
		     int timeDerivative, double time)

  /******************************************************************************
   *
   * extract_nodal_eb_vec:
   *
   *      This function extracts the a particular nodal variable specified
   *  by the program arguments and loads it up into a global vector.
   *  This routine only operates on one element block.
   *
   * This function puts the nodal values of the selected variable
   * into a global solution vector which contains all the mesh nodes,
   * and interpolates the mid-side and centroid values of 
   * all variables with Q1 interpolation on a
   * 9-NODE mesh and interpolates to find their values at the mid-side
   * nodes and at the centroid
   *
   *  Input
   * --------
   *  sol_vec[] = Current global solution vector
   *  var_no    = Variable type to be extracted
   *  ktype     = sub_var number of the variable type to be extracted
   *  matIndex  = material index of the variable to be extracted.
   *             -1 : extract the nonspecific variable
   *             -2 : extract the first variable with var_no no
   *                  matter what material index.
   *  exo       = Exodus database structure
   *  timeDerivative = Are we extracting a time derivative? if so,
   *              then this is true. If not, false.
   *
   * Output
   * -------
   *  nodal_vec[] = nodal vector which receives the value
   *                of the extracted vector. (length number
   *                of nodes)
   *********************************************************************************/
{
  int mn, e_start, e_end, ielem, ielem_type, ip_total, num_local_nodes;
  int ielem_dim, iconnect_ptr, i, I, index;
  int ileft, Ileft, iright, Iright, midside;
  int lastSpeciesSum, iDof, j;
  MATRL_PROP_STRUCT *matrl;
  double rho;
#ifdef DEBUG_HKM
  int nunks, interpType;
#endif

  /*
   * Find out the material number, mn, from the element block index
   */
  mn = Matilda[eb_index];
  matrl = mp_glob[mn];

  /* 
   * Assign local pointer pd to appropriate material
   */
  pd = pd_glob[mn];

  /*
   *  Check for the existence of a special case for the sum of
   *  the last species constraint condition
   */
  lastSpeciesSum = FALSE;
  if (var_no == MASS_FRACTION) {
    if (matrl->Num_Species_Eqn < matrl->Num_Species) {
      if (ktype == matrl->Num_Species - 1) lastSpeciesSum = TRUE;
    }
  }

  /*
   *  Found out the beginning element number and ending element number
   *  from the element block index
   */
  e_start =  exo->eb_ptr[eb_index];
  e_end   =  exo->eb_ptr[eb_index+1];

  /*
   *  Loop over elements in the element block
   */
  for (ielem = e_start; ielem < e_end; ielem++) {

    /*
     *  Get the element type for this element -> Isn't this the
     *  same for all elements in the element block?
     *  
     */
    ielem_type      = Elem_Type(exo, ielem);

    /*
     *  Get the total number of quadrature points
     */
    ip_total        = elem_info(NQUAD, ielem_type); 

    /*
     *  Get the dimensionality of the elements in the element block
     */
    ielem_dim       = elem_info(NDIM, ielem_type);

    /*
     * Number of local nodes in the element
     */
    num_local_nodes = elem_info(NNODES, ielem_type);

    /*
     *  find ptr to beginning of this element's connectivity list 
     *
     */
    iconnect_ptr = Proc_Connect_Ptr[ielem]; 

    /* 
     * First, place the known nodal variable values for this
     * particular variable and type into the nodal vector.
     *
     * This will zero out the midside node for conjugate problems
     * at the interface between material.
     * It needs to be fixed! -RRR
     *
     *  The field variable is zero where it is not defined
     */

    for (i = 0; i < num_local_nodes; i++) {
      I = Proc_Elem_Connect[iconnect_ptr + i];
      iDof = 0;
      /*
       * HKM -> Special compatibility section
       */
#ifdef DEBUG_HKM
      interpType = pd_glob[mn]->i[var_no];
      nunks = node_info(i, ielem_type, var_no, I);
      if (nunks > 1) {
	if (interpType == I_P0 || interpType == I_P1) {
	} else {
	  if (((exo->eb_id[eb_index] + 1) % 2) == 0) {
	    iDof = 0;
	  } else {
	    iDof = 1;
	  }
	}
      }
#endif
      if (lastSpeciesSum) {
	index = Index_Solution(I, var_no, 0, iDof, matIndex);
	if (index != -1) {
	  nodal_vec[I] = 0.0;
	  for (j = 0; j < matrl->Num_Species_Eqn; j++) {
	    index = Index_Solution(I, var_no, j, iDof, matIndex);
	    nodal_vec[I] -= sol_vec[index];
	  }
	  switch (matrl->Species_Var_Type) {
	  case SPECIES_CONCENTRATION:
	      if (matrl->DensityModel == DENSITY_CONSTANT_LAST_CONC) {
		nodal_vec[I] = matrl->u_density[0];
	      } else {
		rho = calc_concentration(matrl, FALSE, NULL);
		nodal_vec[I] += rho;
	      }
	      break;
	  case SPECIES_DENSITY:
	      rho = calc_density(matrl, FALSE, NULL, time);
	      nodal_vec[I] += rho;
	      break;
	  default:
	      if (!timeDerivative) {
		nodal_vec[I] += 1.0;
	      }
	      break;
	  }
	}
      } else {
	index = Index_Solution(I, var_no, ktype, iDof, matIndex);
	if (index != -1) {
	  nodal_vec[I] = sol_vec[index];
	} 
      }
    }

    /*
     * Rich's famous patch up for lesserly interpolated variables.
     * Promote quadrilateral Q1 variables to Q2 status, 8 node serendipity
     * at least, and 9-node biquadratic at best.
     */
    /* RRR notes a problem here in 3D. 
     *     Should add check for TRIQUAD_QUAD elem type */

    midside = 0;  
    if (((pd->i[var_no] == I_Q1)   ||
         (pd->i[var_no] == I_Q1_G)   ||
	 (pd->i[var_no] == I_Q1_GP)   ||
	 (pd->i[var_no] == I_Q1_GN)   ||
         (pd->i[var_no] == I_Q1_XV)   ||
         (pd->i[var_no] == I_Q1_XG)   ||
         (pd->i[var_no] == I_Q1_HV)   ||
         (pd->i[var_no] == I_Q1_HG)   ||
         (pd->i[var_no] == I_Q1_HVG)   ||
	 (pd->i[var_no] == I_Q1_D) ||
	 (pd->i[var_no] == I_SP)      )
	&& ((ielem_type == S_BIQUAD_QUAD)  ||
	    (ielem_type == BIQUAD_QUAD)         )) {
      midside = 1;
    }
  
    if (midside) {
      /* now interpolate Q1 variables onto 9-node mesh if needed */
      for (i = 4; i < 8; i++) {
	I = Proc_Elem_Connect[iconnect_ptr + i]; 
	/* 
	 * Double check to insure there really are no dofs here.
	 */
	if (Index_Solution(I, var_no, ktype, 0, matIndex) == -1) {
	  /* 
	   * make node lie halfway between adjacent nodes 
	   * cf. PATRAN local numbering scheme for element.
	   */
	  ileft = i - 4;
	  Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
	  iright = i - 3;
	  if (iright == 4) iright = 0;
	  Iright = Proc_Elem_Connect[iconnect_ptr + iright];
	  nodal_vec[I] = 
	      0.5 * (nodal_vec[Ileft] + nodal_vec[Iright]);
#if 0
          if ((pd->i[var_no] == I_Q1_HV)   ||
              (pd->i[var_no] == I_Q1_HG)   ||
              (pd->i[var_no] == I_Q1_HVG)) nodal_vec[I] = -1.;
#endif
	}
      }
      /*
       *  Only interpolate centroid in  BIQUAD_QUAD
       */
      if (ielem_type == BIQUAD_QUAD) {
	I = Proc_Elem_Connect[iconnect_ptr + 8];
	nodal_vec[I] = 0.0; 
	if ( (Index_Solution(I, var_no, ktype, 0, matIndex) == -1) ||
             /* for P0 jumps, overwrite jump with interpolant */
             (pd->i[var_no] == I_Q1_HV ||
              pd->i[var_no] == I_Q1_HG ||
              pd->i[var_no] == I_Q1_HVG) ) {
	  for (ileft = 0; ileft < 4; ileft++) {
	    Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
	    nodal_vec[I] += 0.25 * nodal_vec[Ileft];
	  }
#if 0
          if ((pd->i[var_no] == I_Q1_HV)   ||
              (pd->i[var_no] == I_Q1_HG)   ||
              (pd->i[var_no] == I_Q1_HVG)) nodal_vec[I] = -1.;
#endif
	}     
      }
    } /* END if (midside) */
  } /* END for (ielem = e_start; ielem < e_end; ielem++) */
  return;
}
コード例 #2
0
ファイル: gmx_density.c プロジェクト: schlaicha/gromacs
int gmx_density(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes partial densities across the box, using an index file.[PAR]",
        "For the total density of NPT simulations, use [gmx-energy] instead.",
        "[PAR]",

        "Option [TT]-center[tt] performs the histogram binning relative to the center",
        "of an arbitrary group, in absolute box coordinates. If you are calculating",
        "profiles along the Z axis box dimension bZ, output would be from -bZ/2 to",
        "bZ/2 if you center based on the entire system.",
        "Note that this behaviour has changed in Gromacs 5.0; earlier versions",
        "merely performed a static binning in (0,bZ) and shifted the output. Now",
        "we compute the center for each frame and bin in (-bZ/2,bZ/2).[PAR]",

        "Option [TT]-symm[tt] symmetrizes the output around the center. This will",
        "automatically turn on [TT]-center[tt] too.",

        "Option [TT]-relative[tt] performs the binning in relative instead of absolute",
        "box coordinates, and scales the final output with the average box dimension",
        "along the output axis. This can be used in combination with [TT]-center[tt].[PAR]",

        "Densities are in kg/m^3, and number densities or electron densities can also be",
        "calculated. For electron densities, a file describing the number of",
        "electrons for each type of atom should be provided using [TT]-ei[tt].",
        "It should look like:[BR]",
        "   [TT]2[tt][BR]",
        "   [TT]atomname = nrelectrons[tt][BR]",
        "   [TT]atomname = nrelectrons[tt][BR]",
        "The first line contains the number of lines to read from the file.",
        "There should be one line for each unique atom name in your system.",
        "The number of electrons for each atom is modified by its atomic",
        "partial charge.[PAR]",

        "IMPORTANT CONSIDERATIONS FOR BILAYERS[PAR]",
        "One of the most common usage scenarios is to calculate the density of various",
        "groups across a lipid bilayer, typically with the z axis being the normal",
        "direction. For short simulations, small systems, and fixed box sizes this",
        "will work fine, but for the more general case lipid bilayers can be complicated.",
        "The first problem that while both proteins and lipids have low volume",
        "compressibility, lipids have quite high area compressiblity. This means the",
        "shape of the box (thickness and area/lipid) will fluctuate substantially even",
        "for a fully relaxed system. Since Gromacs places the box between the origin",
        "and positive coordinates, this in turn means that a bilayer centered in the",
        "box will move a bit up/down due to these fluctuations, and smear out your",
        "profile. The easiest way to fix this (if you want pressure coupling) is",
        "to use the [TT]-center[tt] option that calculates the density profile with",
        "respect to the center of the box. Note that you can still center on the",
        "bilayer part even if you have a complex non-symmetric system with a bilayer",
        "and, say, membrane proteins - then our output will simply have more values",
        "on one side of the (center) origin reference.[PAR]",

        "Even the centered calculation will lead to some smearing out the output",
        "profiles, as lipids themselves are compressed and expanded. In most cases",
        "you probably want this (since it corresponds to macroscopic experiments),",
        "but if you want to look at molecular details you can use the [TT]-relative[tt]",
        "option to attempt to remove even more of the effects of volume fluctuations.[PAR]",

        "Finally, large bilayers that are not subject to a surface tension will exhibit",
        "undulatory fluctuations, where there are 'waves' forming in the system.",
        "This is a fundamental property of the biological system, and if you are",
        "comparing against experiments you likely want to include the undulation",
        "smearing effect.",
        "",
    };

    output_env_t       oenv;
    static const char *dens_opt[] =
    { NULL, "mass", "number", "charge", "electron", NULL };
    static int         axis        = 2;  /* normal to memb. default z  */
    static const char *axtitle     = "Z";
    static int         nslices     = 50; /* nr of slices defined       */
    static int         ngrps       = 1;  /* nr. of groups              */
    static gmx_bool    bSymmetrize = FALSE;
    static gmx_bool    bCenter     = FALSE;
    static gmx_bool    bRelative   = FALSE;

    t_pargs            pa[]        = {
        { "-d", FALSE, etSTR, {&axtitle},
          "Take the normal on the membrane in direction X, Y or Z." },
        { "-sl",  FALSE, etINT, {&nslices},
          "Divide the box in this number of slices." },
        { "-dens",    FALSE, etENUM, {dens_opt},
          "Density"},
        { "-ng",       FALSE, etINT, {&ngrps},
          "Number of groups of which to compute densities." },
        { "-center",   FALSE, etBOOL, {&bCenter},
          "Perform the binning relative to the center of the (changing) box. Useful for bilayers." },
        { "-symm",     FALSE, etBOOL, {&bSymmetrize},
          "Symmetrize the density along the axis, with respect to the center. Useful for bilayers." },
        { "-relative", FALSE, etBOOL, {&bRelative},
          "Use relative coordinates for changing boxes and scale output by average dimensions." }
    };

    const char        *bugs[] = {
        "When calculating electron densities, atomnames are used instead of types. This is bad.",
    };

    double           **density;        /* density per slice          */
    real               slWidth;        /* width of one slice         */
    char              *grpname_center; /* centering group name     */
    char             **grpname;        /* groupnames                 */
    int                nr_electrons;   /* nr. electrons              */
    int                ncenter;        /* size of centering group    */
    int               *ngx;            /* sizes of groups            */
    t_electron        *el_tab;         /* tabel with nr. of electrons*/
    t_topology        *top;            /* topology               */
    int                ePBC;
    atom_id           *index_center;   /* index for centering group  */
    atom_id          **index;          /* indices for all groups     */
    int                i;

    t_filenm           fnm[] = { /* files for g_density       */
        { efTRX, "-f", NULL,  ffREAD },
        { efNDX, NULL, NULL,  ffOPTRD },
        { efTPR, NULL, NULL,  ffREAD },
        { efDAT, "-ei", "electrons", ffOPTRD }, /* file with nr. of electrons */
        { efXVG, "-o", "density", ffWRITE },
    };

#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs,
                           &oenv))
    {
        return 0;
    }

    if (bSymmetrize && !bCenter)
    {
        fprintf(stderr, "Can not symmetrize without centering. Turning on -center\n");
        bCenter = TRUE;
    }
    /* Calculate axis */
    axis = toupper(axtitle[0]) - 'X';

    top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC); /* read topology file */
    if (dens_opt[0][0] == 'n')
    {
        for (i = 0; (i < top->atoms.nr); i++)
        {
            top->atoms.atom[i].m = 1;
        }
    }
    else if (dens_opt[0][0] == 'c')
    {
        for (i = 0; (i < top->atoms.nr); i++)
        {
            top->atoms.atom[i].m = top->atoms.atom[i].q;
        }
    }

    snew(grpname, ngrps);
    snew(index, ngrps);
    snew(ngx, ngrps);

    if (bCenter)
    {
        fprintf(stderr,
                "\nNote: that the center of mass is calculated inside the box without applying\n"
                "any special periodicity. If necessary, it is your responsibility to first use\n"
                "trjconv to make sure atoms in this group are placed in the right periodicity.\n\n"
                "Select the group to center density profiles around:\n");
        get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ncenter,
                  &index_center, &grpname_center);
    }
    else
    {
        ncenter = 0;
    }

    fprintf(stderr, "\nSelect %d group%s to calculate density for:\n", ngrps, (ngrps > 1) ? "s" : "");
    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), ngrps, ngx, index, grpname);

    if (dens_opt[0][0] == 'e')
    {
        nr_electrons =  get_electrons(&el_tab, ftp2fn(efDAT, NFILE, fnm));
        fprintf(stderr, "Read %d atomtypes from datafile\n", nr_electrons);

        calc_electron_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density,
                              &nslices, top, ePBC, axis, ngrps, &slWidth, el_tab,
                              nr_electrons, bCenter, index_center, ncenter,
                              bRelative, oenv);
    }
    else
    {
        calc_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top,
                     ePBC, axis, ngrps, &slWidth, bCenter, index_center, ncenter,
                     bRelative, oenv);
    }

    plot_density(density, opt2fn("-o", NFILE, fnm),
                 nslices, ngrps, grpname, slWidth, dens_opt,
                 bCenter, bRelative, bSymmetrize, oenv);

    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");  /* view xvgr file */
    return 0;
}
コード例 #3
0
ファイル: sph.cpp プロジェクト: xyuan/SPH-DEM
void Nsph::init_density(Cparticle &p) {
   p.dens = 0.0;
   calc_density(p,p);
}
コード例 #4
0
/*---------------------------------------------------------------------------------------------
 * (function: calc_transition_density)
 *-------------------------------------------------------------------------------------------*/
void calc_transition_density(netlist_t *netlist)
{
	int i, j, m;
	activation_t *act_data;

	/* progress from the primary inputs (in the forward level 0) to each stage */
	for (i = 0; i < netlist->num_forward_levels; i++)
	{
		for (j = 0; j < netlist->num_at_forward_level[i]; j++)
		{
			/* initialize the activation data */
			nnode_t *current_node = netlist->forward_levels[i][j];
			act_data = (activation_t*)current_node->node_data;
	
			/* All other levels we pass through the probabilities and calculate Transition prbability for the DEnsity calculation */
			if (current_node->type == BLIF_FUNCTION)
			{
				/* only one output */
				act_data->transition_density = (double*)malloc(sizeof(double)); // only one output
	
				if (current_node->num_input_pins == 1)
				{
					/* If this is a Constant, NOT or a BUFFER then the transition density is easy to calculate */
					nnode_t *input_node = current_node->input_pins[0]->net->driver_pin->node;
					int input_node_pin = current_node->input_pins[0]->net->driver_pin->pin_node_idx;
					activation_t *input_data = (activation_t*)input_node->node_data;
					oassert(input_node->unique_node_data_id == ACTIVATION);

					if ((current_node->associated_function[0] == 0) && (current_node->associated_function[1] == 0))
						/* CONSTANT 0 */
						act_data->transition_density[0] = 0;
					if ((current_node->associated_function[0] == 0) && (current_node->associated_function[1] == 1))
						/* BUFFER */
						act_data->transition_density[0] = input_data->transition_density[input_node_pin];
					if ((current_node->associated_function[0] == 1) && (current_node->associated_function[1] == 0))
						/* NOT */
						act_data->transition_density[0] = input_data->transition_density[input_node_pin];
					if ((current_node->associated_function[0] == 1) && (current_node->associated_function[1] == 1))
						/* CONSTANT 1 */
						act_data->transition_density[0] = 0;
				}
				else
				{
					double density_val = 0.0;

					/* calculate the transition densities sumof(D(y)*P(boolean_diff, y) */
					for (m = 0; m < current_node->num_input_pins; m++)
					{
						short *boolean_difference_function;

						/* calculate hte boolean difference */
						boolean_difference_function = boolean_difference(current_node, m);

						/* now calculate the denisty of this input ... sum of */
						density_val = density_val + calc_density(current_node, m, boolean_difference_function);

						/* free the array */
						free(boolean_difference_function);
					}

					act_data->transition_density[0] = density_val;
				}
			}
			else if (current_node->type == FF_NODE)
			{
				nnode_t *input_node = current_node->input_pins[0]->net->driver_pin->node;
				int input_node_pin = current_node->input_pins[0]->net->driver_pin->pin_node_idx;
				activation_t *input_data = (activation_t*)input_node->node_data;
				oassert(input_node->unique_node_data_id == ACTIVATION);
		
				/* just store since allocated in the initialization */
				act_data->transition_density = (double*)malloc(sizeof(double));
				act_data->transition_density[0] = 2 * (input_data->static_probability[input_node_pin] * (1-input_data->static_probability[input_node_pin])); 
			}
			else if (current_node->type == OUTPUT_NODE)
			{
				nnode_t *input_node = current_node->input_pins[0]->net->driver_pin->node;
				int input_node_pin = current_node->input_pins[0]->net->driver_pin->pin_node_idx;
				activation_t *input_data = (activation_t*)input_node->node_data;
				oassert(input_node->unique_node_data_id == ACTIVATION);
		
				/* allocate and stre through */
				act_data->transition_density = (double*)malloc(sizeof(double));
				act_data->transition_density[0] = input_data->static_probability[input_node_pin];
			}
			else if ((current_node->type == INPUT_NODE) || (current_node->type == VCC_NODE) || (current_node->type == GND_NODE))
			{
				oassert(current_node->unique_node_data_id == ACTIVATION);
			}
			else
			{
				oassert(FALSE);
			}
		}
	}
}