Пример #1
0
void _HeatingForce_ValueAtParticle(
	void*				heatingForce, 
	IntegrationPointsSwarm*		swarm, 
	Element_LocalIndex		lElement_I, 
	IntegrationPoint*		particle,
	double*				value ) 
{
	HeatingForce*			self 		= (HeatingForce*)heatingForce;
	Material*			material;
	BuoyancyMaterial_MaterialExt*	materialExt;
	
	material = IntegrationPointsSwarm_GetMaterialOn( swarm, particle );
	materialExt = ExtensionManager_Get( material->extensionMgr, material, self->buoyancyMaterial->materialExtHandle );
	*value = materialExt->extensions[self->materialIndex];
}
Пример #2
0
void lecode_tools_Isostasy_AverageBody(lecode_tools_Isostasy *self,
                                       double** _avg_density, double** _rho_zero_density,
                                       double** _phi)
{
   FeMesh *mesh;
   ElementType *el_type;
   IntegrationPointsSwarm *swarm;
   double *local_density, *global_density;
   double *local_vol, *global_vol;
   double *local_rho_zero_vol, *global_rho_zero_vol;
   double *local_rho_zero_density, *global_rho_zero_density;
   double *local_phi, *global_phi, temp, tempDot;
   int cell, num_particles, num_dims, num_els;
   IntegrationPoint *particle;
   double jac_det;
   double density, alpha, densityFinal;
   Material *mat;
   Bool oneToMany;
   Grid* elGrid;
   int elInds[3], arraySize, arrayPos;
   int ii, jj;

   mesh = self->mesh;
   elGrid = *Mesh_GetExtension( mesh, Grid**,  mesh->elGridId );
   num_dims = Mesh_GetDimSize(mesh);
   swarm = self->swarm;
   num_els = FeMesh_GetElementLocalSize(mesh);

   arraySize=0;
   if ( num_dims == 2 ) arraySize = elGrid->sizes[0];
   else if ( num_dims == 3 ) arraySize = elGrid->sizes[0]*elGrid->sizes[self->zontalAxis];
   else assert(0);

   /* Allocate for the column values. */
   local_vol = (double*)malloc( arraySize*sizeof(double) );
   memset( local_vol, 0, arraySize*sizeof(double) );
   local_density = (double*)malloc( arraySize*sizeof(double) );
   memset( local_density, 0, arraySize*sizeof(double) );
   local_rho_zero_vol = (double*)malloc( arraySize*sizeof(double) );
   memset( local_rho_zero_vol, 0, arraySize*sizeof(double) );
   local_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   memset( local_rho_zero_density, 0, arraySize*sizeof(double) );
   local_phi = (double*)malloc( arraySize*sizeof(double) );
   memset( local_phi, 0, arraySize*sizeof(double) );

   /* Initialise temperature. */
   temp = 0.0;

   oneToMany = Stg_Class_IsInstance(swarm->mapper, OneToManyMapper_Type);

   for (ii = 0; ii < num_els; ii++)
   {

      /* Make sure the element is beneath the surface. */
      Grid_Lift( elGrid, FeMesh_ElementDomainToGlobal( mesh, ii ), elInds );
      if ( self->surfaceIdx != -1 && elInds[self->vertAxis] >= self->surfaceIdx )
         continue;

      el_type = FeMesh_GetElementType(mesh, ii);
      cell = CellLayout_MapElementIdToCellId(swarm->cellLayout, ii);
      num_particles = swarm->cellParticleCountTbl[cell];

      for (jj = 0; jj < num_particles; jj++)
      {

         particle = (IntegrationPoint*)Swarm_ParticleInCellAt(swarm, cell, jj);
         jac_det = ElementType_JacobianDeterminant(el_type, mesh, ii, particle->xi, num_dims);

         if(!self->ppcManager){
            density = IntegrationPointMapper_GetDoubleFromMaterial(
                         swarm->mapper, particle, self->buoyancy->materialExtHandle,
                         offsetof(BuoyancyForceTerm_MaterialExt, density) );
            alpha = IntegrationPointMapper_GetDoubleFromMaterial(
                       swarm->mapper, particle, self->buoyancy->materialExtHandle,
                       offsetof(BuoyancyForceTerm_MaterialExt, alpha) );

            if (self->tempField)
            {
               FeVariable_InterpolateFromMeshLocalCoord(self->tempField, self->tempField->feMesh,
                     ii, particle->xi, &temp);
               FeVariable_InterpolateFromMeshLocalCoord(self->tempDotField, self->tempDotField->feMesh,
                     ii, particle->xi, &tempDot);
            }

            densityFinal = density*(1.0 - alpha*temp);

         } else {
            int err;
            /* Density */
            err = PpcManager_Get( self->ppcManager, ii, particle, self->densityID, &densityFinal );
            assert(!err);
         }

         arrayPos = elInds[0];
         if ( num_dims == 3 ) arrayPos += elInds[self->zontalAxis]*elGrid->sizes[0];

         local_vol[arrayPos] += particle->weight*jac_det;
         local_density[arrayPos] += particle->weight*jac_det*densityFinal;

         if (!oneToMany)
         {
            mat = IntegrationPointsSwarm_GetMaterialOn(swarm, particle);
            if (mat->index == self->rho_zero_mat->index)
            {
               local_rho_zero_vol[arrayPos] += particle->weight*jac_det;
               local_rho_zero_density[arrayPos] += particle->weight*jac_det*densityFinal;
            }
         }
         else
         {
            OneToManyRef *ref;
            int cnt;
            int kk;

            ref = OneToManyMapper_GetMaterialRef(swarm->mapper, particle);
            cnt = 0;
            for (kk = 0; kk < ref->numParticles; kk++)
            {
               mat = MaterialPointsSwarm_GetMaterialAt(((OneToManyMapper*)swarm->mapper)->materialSwarm, ref->particleInds[kk]);
               if (mat->index == self->rho_zero_mat->index)
                  cnt++;
            }

            if (2*cnt > ref->numParticles)
            {
               local_rho_zero_vol[arrayPos] += particle->weight*jac_det;
               local_rho_zero_density[arrayPos] += particle->weight*jac_det*densityFinal;
            }
         }

         if (_phi)
         {
            local_phi[arrayPos] += particle->weight*jac_det*(-density*alpha*tempDot);
         }
      }
   }

   /* Allocate for the global column values. */
   global_vol = (double*)malloc( arraySize*sizeof(double) );
   global_density = (double*)malloc( arraySize*sizeof(double) );
   global_rho_zero_vol = (double*)malloc( arraySize*sizeof(double) );
   global_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   global_phi = (double*)malloc( arraySize*sizeof(double) );

   MPI_Allreduce(local_vol, global_vol, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_density, global_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_rho_zero_vol, global_rho_zero_vol, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_rho_zero_density, global_rho_zero_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   if (_phi)
      MPI_Allreduce(local_phi, global_phi, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

   free( local_vol );
   free( local_density );
   free( local_rho_zero_vol );
   free( local_rho_zero_density );
   free( local_phi );

   if ( self->avg )
   {
      for ( ii = 1; ii < arraySize; ii++ )
      {
         global_vol[0] += global_vol[ii];
         global_density[0] += global_density[ii];
         global_rho_zero_vol[0] += global_rho_zero_vol[ii];
         global_rho_zero_density[0] += global_rho_zero_density[ii];
         if ( _phi )
            global_phi[0] += global_phi[ii];
      }
   }

   /* Calculate results. */
   *_avg_density = (double*)malloc( arraySize*sizeof(double) );
   *_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   if (_phi)
      *_phi = (double*)malloc( arraySize*sizeof(double) );
   for ( ii = 0; ii < arraySize; ii++ )
   {
      (*_avg_density)[ii] = (global_vol[ii] > 1e-7) ? global_density[ii]/global_vol[ii] : 0.0;
      (*_rho_zero_density)[ii] = (global_rho_zero_vol[ii] > 1e-7) ? global_rho_zero_density[ii]/global_rho_zero_vol[ii] : 0.0;
      if (_phi)
         (*_phi)[ii] = (global_vol[ii] > 1e-7) ? global_phi[ii]/global_vol[ii] : 0.0;
      if ( self->avg )
         break;
   }

   /*
       printf("Global mean density: %g\n", (*_avg_density)[0]);
       printf("Global mean rho_0 density: %g\n", (*_rho_zero_density)[0]);
       printf("Global phi/vol: %g\n", (*_phi)[0]);
   */

   free( global_vol );
   free( global_density );
   free( global_rho_zero_vol );
   free( global_rho_zero_density );
   free( global_phi );
}