double _Pouliquen_etal_GetYieldCriterion( 
			void*                            pouliquen_etal,
			ConstitutiveMatrix*              constitutiveMatrix,
			MaterialPointsSwarm*             materialPointsSwarm,
			Element_LocalIndex               lElement_I,
			MaterialPoint*                   materialPoint,
			Coord                            xi )
{
	Pouliquen_etal*                    self             = (Pouliquen_etal*) pouliquen_etal;

	double                            frictionalStrength;
	double                            pressure;
	Pouliquen_etal_Particle*          particleExt;
	double                            strainRateInv;
	
	particleExt = (Pouliquen_etal_Particle*)ExtensionManager_Get( materialPointsSwarm->particleExtensionMgr, materialPoint, self->particleExtHandle );

	FeVariable_InterpolateWithinElement( self->pressureField, lElement_I, xi, &pressure );
	FeVariable_InterpolateWithinElement( self->strainRateInvField, lElement_I, xi, &strainRateInv );

	particleExt->pressure      = pressure;
	particleExt->strainRateInv = strainRateInv;

	frictionalStrength = self->mu_s * pressure;
	//the following is to ensure that every particle is yielding
	//frictionalStrength = -1.0;	

	return frictionalStrength;
}
void _GALENonNewtonian_ModifyConstitutiveMatrix( 
		void*                                              rheology, 
		ConstitutiveMatrix*                                constitutiveMatrix,
		MaterialPointsSwarm*                               swarm,
		Element_LocalIndex                                 lElement_I,
		MaterialPoint*                                     materialPoint,
		Coord                                              xi )
{
	GALENonNewtonian*	              self              = (GALENonNewtonian*) rheology;
	double                        strainRateInv;
	double                        minVis;
	double                        maxVis;
	double                        viscosity;
	double                        n, T_0, A, T;
	Stream* errorStream = Journal_Register( Error_Type,
                                                GALENonNewtonian_Type );

	n = self->n;
        T_0=self->T_0;
        A=self->A;
	minVis = self->minViscosity;
	maxVis = self->maxViscosity;

        FeVariable_InterpolateWithinElement(self->temperatureField,
                                            lElement_I,xi,&T);
        Journal_Firewall(n!=0 && T!=0 && A!=0,errorStream,
                         "Error in GALENonNewtonian: T, n, and A must all be non-zero:\n\tT=%g\n\tn=%g\n\tA=%g\n",T,n,A);

        viscosity=exp(T_0/(n*T))/(2*A);

	if ( fabs( n - 1.0 ) > 1.0e-10 )
          {
            if ( !constitutiveMatrix->previousSolutionExists )
              /* on the first ever solve, use a ref strainrate */
              {
                strainRateInv = self->refStrainRate;
              }
            else
              {
                /* Calculate Parameters */
                FeVariable_InterpolateWithinElement(self->strainRateInvField,
                                                    lElement_I,xi,&strainRateInv);
              }
            /* Calculate New Viscosity */
            viscosity*= pow(strainRateInv,1.0/n - 1.0);
          }
        if(maxVis!=0 && viscosity>maxVis)
          {
            viscosity=maxVis;
          }
        if(minVis!=0 && viscosity<minVis)
          {
            viscosity=minVis;
          }
	ConstitutiveMatrix_SetIsotropicViscosity(constitutiveMatrix,viscosity);
}
double SemiLagrangianIntegratorSuite_EvaluateError( FeVariable* phiField, FeVariable* phiOldField, Swarm* gaussSwarm ) {
   FeMesh*			feMesh		= phiField->feMesh;
   GaussParticleLayout*	particleLayout 	= (GaussParticleLayout*)gaussSwarm->particleLayout;
   Index			lElement_I, lCell_I;
   unsigned		nDims		= Mesh_GetDimSize( feMesh );
   unsigned		numMeshElements	= Mesh_GetLocalSize( feMesh, nDims );
   double			elementError;
   double			lErrorSq	= 0.0;
   double			lAnalyticSq 	= 0.0;
   double			gErrorSq, gAnalyticSq, gErrorNorm;
   IntegrationPoint*	gaussPoint;
   unsigned		gaussPoint_I, numGaussPoints;
   double			initialValue, finalValue;
   double			elErrorSq, elAnalyticSq;
   ElementType*		elementType;
   double			detJac;

   for( lElement_I = 0; lElement_I < numMeshElements; lElement_I++ ) {
      lCell_I = CellLayout_MapElementIdToCellId( gaussSwarm->cellLayout, lElement_I );
      numGaussPoints = _GaussParticleLayout_InitialCount( particleLayout, NULL, lCell_I );

      elementType = FeMesh_GetElementType( feMesh, lElement_I );

      elErrorSq = 0.0;
      elAnalyticSq = 0.0;

      for( gaussPoint_I = 0; gaussPoint_I < numGaussPoints; gaussPoint_I++ ) {
         gaussPoint = (IntegrationPoint*) Swarm_ParticleInCellAt( gaussSwarm, lCell_I, gaussPoint_I );
         FeVariable_InterpolateWithinElement( phiOldField, lElement_I, gaussPoint->xi, &initialValue );
         FeVariable_InterpolateWithinElement( phiField, lElement_I, gaussPoint->xi, &finalValue );

         detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, gaussPoint->xi, nDims );

         elErrorSq += ( finalValue - initialValue ) * ( finalValue - initialValue ) * gaussPoint->weight * detJac;
         elAnalyticSq += ( initialValue * initialValue ) * gaussPoint->weight * detJac;
      }

      elementError = sqrt( elErrorSq ) / sqrt( elAnalyticSq );

      lErrorSq += elErrorSq;
      lAnalyticSq += elAnalyticSq;
   }

   MPI_Allreduce( &lErrorSq, &gErrorSq, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
   MPI_Allreduce( &lAnalyticSq, &gAnalyticSq, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );

   gErrorNorm = sqrt( gErrorSq ) / sqrt( gAnalyticSq );

   return gErrorNorm;
}
Ejemplo n.º 4
0
Bool _SwarmAdvector_TimeDeriv_Quicker4IrregularMesh( void* swarmAdvector, Index array_I, double* timeDeriv ) {
   SwarmAdvector*      self          = (SwarmAdvector*) swarmAdvector;
   FeVariable*      velocityField = (FeVariable*) self->velocityField;
   GlobalParticle* particle=NULL;
   FeMesh_ElementType* eType=NULL;
   double xi[3];
   unsigned cellID;

   particle = (GlobalParticle*)Swarm_ParticleAt( self->swarm, array_I );
   assert( particle );

   // get particle's cell/element id - ASSUMES 1-to-1 cellID to elementID
   // if not local return False
   cellID = CellLayout_CellOf( self->swarm->cellLayout, particle );
   if( cellID >= CellLayout_CellLocalCount( self->swarm->cellLayout ) )
      return False;

   /* below is some funky code to optimise time in retrieving :
      Why? for an irregular mesh the function CellLayout_CellOf() will actually
      evaulate the local coordinate and store it on a temporary valiable (on 'FeMesh_ElementType->local[]')
      we will access below, instead of re-evaluating the GlobaToLocal loop (i.e. Newton-Raphson iteration)
      with a function like FeMesh_CoordGlobalToLocal().

      This ASSUMES that the temporary storage isn't modified between CellLayout_CellOf() and here.
   */

   // get particle's local coordinate
   eType = (FeMesh_ElementType*)velocityField->feMesh->elTypes[velocityField->feMesh->elTypeMap[cellID]];
   FeMesh_ElementTypeGetLocal( eType, xi );

   // do interpolation
   FeVariable_InterpolateWithinElement( velocityField, cellID, xi, timeDeriv );

   return True;
}
Ejemplo n.º 5
0
double IntegrateField( FeVariable* tempField, IntegrationPointsSwarm* swarm ) {
	FeMesh*			mesh	= tempField->feMesh;
	unsigned		el_i;
	unsigned		cell_i;
	unsigned		point_i;
	double			lTemp	= 0.0;
	double			gTemp;
	double			temp;
	double			detJac;
	IntegrationPoint*	point;
	ElementType*		elType;
	unsigned		dim	= Mesh_GetDimSize( mesh );
	
	for( el_i = 0; el_i < Mesh_GetLocalSize( mesh, dim ); el_i++ ) {
		cell_i = CellLayout_MapElementIdToCellId( swarm->cellLayout, el_i );
		elType = FeMesh_GetElementType( mesh, el_i );
		
		for( point_i = 0; point_i < swarm->cellParticleCountTbl[cell_i]; point_i++ ) {
			point = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_i, point_i );

			FeVariable_InterpolateWithinElement( tempField, el_i, point->xi, &temp );
			detJac = ElementType_JacobianDeterminant( elType, mesh, el_i, point->xi, dim );

			lTemp += detJac * point->weight * temp;
		}
	}

	MPI_Allreduce( &lTemp, &gTemp, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );

	return gTemp;
}
void _NonNewtonianAbs_ModifyConstitutiveMatrix( 
		void*                                              rheology, 
		ConstitutiveMatrix*                                constitutiveMatrix,
		MaterialPointsSwarm*                               swarm,
		Element_LocalIndex                                 lElement_I,
		MaterialPoint*                                     materialPoint,
		Coord                                              xi )
{
	NonNewtonianAbs*	              self              = (NonNewtonianAbs*) rheology;
	double                        strainRateInv;
	double                        viscosity;
	double                        n;

	/* On the first ever solve we use the default strain rate */
	if ( !constitutiveMatrix->previousSolutionExists ) {
	  strainRateInv = self->defaultStrainRateInvariant;
   } else {
     FeVariable_InterpolateWithinElement( self->strainRateInvField, lElement_I, xi, &strainRateInv );
   }

	if ( strainRateInv == 0 )
	  return;

	n = self->stressExponent;

	if ( n == 0.0 )
		return;

	/* Calculate New Viscosity */
	viscosity = self->initialViscosity * pow(strainRateInv, 1.0/n - 1.0);
	ConstitutiveMatrix_SetIsotropicViscosity( constitutiveMatrix, viscosity );
}
Bool _RateFieldTimeIntegrator_TimeDerivative( void* rateFieldTimeIntegrator, Index lParticle_I, double* timeDeriv ) {
   RateFieldTimeIntegrator*    self   = (RateFieldTimeIntegrator*) rateFieldTimeIntegrator;
   MaterialPoint*          materialPoint = (MaterialPoint*) Swarm_ParticleAt( self->swarm, lParticle_I );
   Element_LocalIndex      lElement_I = materialPoint->owningCell; /** assume that swarmratefield uses same mesh as particles */

   FeVariable_InterpolateWithinElement( self->rateField, lElement_I, materialPoint->coord, timeDeriv );

   return True;

}
Ejemplo n.º 8
0
/* New method: sample & surface each element in local coords, faster, handles deformed meshes */
void lucIsosurface_SampleLocal( void* drawingObject)
{
   lucIsosurface*             self               = (lucIsosurface*)drawingObject;
   FeVariable*                feVariable         = (FeVariable*) self->isosurfaceField;
   FeMesh*    		            mesh               = feVariable->feMesh;
   Element_LocalIndex         lElement_I;
   Element_LocalIndex         elementLocalCount  = FeMesh_GetElementLocalSize( mesh );
   int                        i, j, k;
   Vertex***                  vertex;

   vertex = Memory_Alloc_3DArray( Vertex, self->nx, self->ny, self->nz, (Name)"Vertex array" );

   for ( lElement_I = 0 ; lElement_I < elementLocalCount ; lElement_I++ )
   {
      for (i = 0 ; i < self->nx; i++)
      {
         for (j = 0 ; j < self->ny; j++)
         {
            for (k = 0 ; k < self->nz; k++)
            {
               /* Calc position within element in local coords */
               Coord local = {-1.0 + (2.0 * i / self->resolution[ I_AXIS ]), 
                              -1.0 + (2.0 * j / self->resolution[ J_AXIS ]),
                              -1.0 + (2.0 * k / self->resolution[ K_AXIS ])};

               /* Get value at coords (faster using element and local coords) */
               FeVariable_InterpolateWithinElement( feVariable, lElement_I, local, &(vertex[i][j][k].value));

               /* Save local coords and element index for fast interpolation */
               memcpy( vertex[i][j][k].pos, local, 3 * sizeof(double) );
               vertex[i][j][k].element_I = lElement_I;
            }
         }
      }

      if (self->isosurfaceField->dim == 3)
         lucIsosurface_MarchingCubes( self, vertex );

      if (self->isosurfaceField->dim == 2 || self->drawWalls)
         lucIsosurface_DrawWalls( self, vertex );
   }

   /* Free memory */
   Memory_Free( vertex );
}
Ejemplo n.º 9
0
void CreateTriangle(lucIsosurface* self, Vertex* point1, Vertex* point2, Vertex* point3, Bool wall)
{
   Vertex* points[3] = {point1, point2, point3};
   int i;

   if (self->triangleCount >= self->trianglesAlloced)
   {
      self->trianglesAlloced += 100;
      self->triangleList = Memory_Realloc_Array( self->triangleList, Surface_Triangle, self->trianglesAlloced );
   }

   /* Wall flag */
   self->triangleList[self->triangleCount].wall = wall;
 
   for (i=0; i<3; i++)
   {
      double value = 0;
      float *pos = self->triangleList[self->triangleCount].pos[i]; 

      if (self->sampleGlobal)
      {
         /* Check maskField values */
         if ( self->maskField )
         {
            double mvalue;
            FieldVariable_InterpolateValueAt( self->maskField, points[i]->pos, &mvalue);
            /* Don't bother calculating if vertex is masked */
            if (lucDrawingObjectMask_Test( &self->mask, mvalue ) == False) return;
         }

         /* Get global coordinates */
         pos[0] = points[i]->pos[0];
         pos[1] = points[i]->pos[1];
         pos[2] = points[i]->pos[2];
         if (self->isosurfaceField->dim == 2) pos[2] = 0;

         /* Get colourField value */
         if ( self->colourField && self->colourMap)
            FieldVariable_InterpolateValueAt( self->colourField, points[i]->pos, &value);
      }
      else
      {
         FeVariable* field = (FeVariable*)self->isosurfaceField;
         double dpos[3] = {0};

         /* Check maskField values */
         if ( self->maskField )
         {
            double mvalue;
            FeVariable_InterpolateWithinElement( self->maskField, points[i]->element_I, points[i]->pos, &mvalue);
            /* Don't bother calculating if vertex is masked */
            if (lucDrawingObjectMask_Test( &self->mask, mvalue ) == False) return;
         }

         /* Get global coordinates */
         FeMesh_CoordLocalToGlobal( field->feMesh, points[i]->element_I, points[i]->pos, dpos );
         pos[0] = dpos[0];
         pos[1] = dpos[1];
         pos[2] = dpos[2];

         /* Get colourField value */
         if ( self->colourField && self->colourMap)
            FeVariable_InterpolateWithinElement( self->colourField, points[i]->element_I, points[i]->pos, &value);
      }

      /* Copy value */
      self->triangleList[self->triangleCount].value[i] = value;
   }

   self->triangleCount++;
}
Ejemplo n.º 10
0
Bool _SwarmAdvector_TimeDeriv( void* swarmAdvector, Index array_I, double* timeDeriv ) {
  SwarmAdvector*      self          = (SwarmAdvector*) swarmAdvector;
  GeneralSwarm*       swarm         = self->swarm;
  CellLayout*         layout        = swarm->cellLayout;
  FeVariable*         velocityField = (FeVariable*) self->velocityField;
  FeMesh*             mesh          = velocityField->feMesh;
  double*             coord;
  InterpolationResult result;

  /* Get Coordinate of Object using Variable */
  coord = StgVariable_GetPtrDouble( self->variable, array_I );

  // if a non regular mesh and ElementCellLayout use the particle and mesh information to optimise search
  if( !mesh->isRegular &&
      Stg_Class_IsInstance(layout, ElementCellLayout_Type) )
  {
    GlobalParticle*     particle = (GlobalParticle*)Swarm_ParticleAt( swarm, array_I );
    FeMesh_ElementType* eType;
    unsigned            cellID;
    double              xi[3];

    // find the cell/element the particle is in
    cellID = CellLayout_CellOf( layout, particle );

    if( cellID >= CellLayout_CellLocalCount( layout ) ) return False; // if not on local proc report False
    /*
       CellLayout_CellOf() will actually evaulate the local coordinate and store it
       on a temporary valiable (on 'FeMesh_ElementType->local[]'). Below we exploit that
    */

    // get particle's local coordinate - HACKY but efficient
    eType = (FeMesh_ElementType*)mesh->elTypes[mesh->elTypeMap[cellID]];
    FeMesh_ElementTypeGetLocal( eType, xi );

    // do interpoplation
    FeVariable_InterpolateWithinElement( velocityField, cellID, xi, timeDeriv );
    return True;
  }
  else
  {
    // if mesh is regular
    result = FieldVariable_InterpolateValueAt( velocityField, coord, timeDeriv );
  }

  if ( result == OTHER_PROC || result == OUTSIDE_GLOBAL || isinf(timeDeriv[0]) || isinf(timeDeriv[1]) ||
     ( swarm->dim == 3 && isinf(timeDeriv[2]) ) )
  {
    /* construct error message */
    int rank;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );

    char* coordchar;
    if ( swarm->dim == 2 )
        Stg_asprintf(&coordchar, "(%f,%f)", coord[0], coord[1] );
    else
        Stg_asprintf(&coordchar, "(%f,%f,%f)", coord[0], coord[1], coord[2] );

    char* message;
    if ( result == OTHER_PROC )
        Stg_asprintf( &message, "Coordinate appears to belong to another process's domain" );
    else if ( result == OUTSIDE_GLOBAL )
        Stg_asprintf( &message, "Coordinate appears to be outside the global domain" );
    else
        Stg_asprintf( &message, "Velocity appears infinite" );

    free(self->error_msg);
    Stg_asprintf(&self->error_msg, "Unable to determine valid velocity for particle of local id %i "
                                          "with coordinate %s on process rank %i. %s.", array_I, coordchar, rank, message );
    free(message);
    free(coordchar);
    return False;
  }

  return True;
}
double _GALEDruckerPrager_GetYieldCriterion( 
			void*                            druckerPrager,
			ConstitutiveMatrix*              constitutiveMatrix,
			MaterialPointsSwarm*             materialPointsSwarm,
			Element_LocalIndex               lElement_I,
			MaterialPoint*                   materialPoint,
			Coord                            xi )
{
	GALEDruckerPrager*                    self             = (GALEDruckerPrager*) druckerPrager;
        Dimension_Index                   dim = constitutiveMatrix->dim;
	double                            cohesion;
	double                            cohesionAfterSoftening;
	double                            frictionCoefficient;
	double                            frictionCoefficientAfterSoftening;
	double                            minimumYieldStress;
	double                            minimumViscosity;
	double                            effectiveCohesion;
	double                            effectiveFrictionCoefficient;
	double                            frictionalStrength;
	double                            pressure;
	GALEDruckerPrager_Particle*           particleExt;
        Cell_Index                        cell_I;
        Coord                             coord;
        Element_GlobalIndex	          element_gI = 0;
        unsigned		          inds[3];
        Grid*			          elGrid;
        Bool                              inside_boundary;
        double                            factor;
	
	/* Get Parameters From Rheology */
	cohesion                           = self->cohesion;
	cohesionAfterSoftening             = self->cohesionAfterSoftening;
	frictionCoefficient                = self->frictionCoefficient;
	frictionCoefficientAfterSoftening  = self->frictionCoefficientAfterSoftening;
	minimumYieldStress                 = self->minimumYieldStress;
	minimumViscosity                   = self->minimumViscosity;
	
	particleExt = (GALEDruckerPrager_Particle*)ExtensionManager_Get( materialPointsSwarm->particleExtensionMgr, materialPoint, self->particleExtHandle );

        if( self->pressureField )
          FeVariable_InterpolateWithinElement( self->pressureField, lElement_I, xi, &pressure );
        else {
          SwarmVariable_ValueAt( self->swarmPressure,
                                 constitutiveMatrix->currentParticleIndex,
                                 &pressure );
        }

        cell_I=CellLayout_MapElementIdToCellId(materialPointsSwarm->cellLayout,
                                               lElement_I );
        FeMesh_CoordLocalToGlobal(self->pressureField->feMesh, cell_I, xi, coord);
        if(self->hydrostaticTerm)
          {
            pressure+=HydrostaticTerm_Pressure(self->hydrostaticTerm,coord);
          }

        /* Normally we add the average of the trace of the stress.
           With compressible material, you have to do it.  But with
           stabilized linear pressure elements, the non-zero trace is
           a numerical artifact.  So we do not add it. */

/*   pressure+=self->trace/dim; */

        /* Calculate frictional strength.  We modify the friction and
           cohesion because we have grouped terms from the normal
           stresses and moved it to the yield indicator. */
	

        /* Big song and dance to see if we are at a boundary that we care about */
        elGrid = *(Grid**)ExtensionManager_Get(self->pressureField->feMesh->info,
                                               self->pressureField->feMesh,
self->pressureField->feMesh->elGridId );
  
        element_gI = FeMesh_ElementDomainToGlobal( self->pressureField->feMesh, lElement_I );
        RegularMeshUtils_Element_1DTo3D( self->pressureField->feMesh, element_gI, inds );
  
        inside_boundary=(self->boundaryBottom && inds[1]==0)
          || (self->boundaryTop && inds[1]==elGrid->sizes[1]-1)
          || (self->boundaryLeft && inds[0]==0)
          || (self->boundaryRight && inds[0]==elGrid->sizes[0]-1)
          || (dim==3 && ((self->boundaryBack && inds[2]==0)
                         || (self->boundaryFront && inds[2]==elGrid->sizes[2]-1)));

        effectiveFrictionCoefficient =
          _GALEDruckerPrager_EffectiveFrictionCoefficient( self, materialPoint,
                                                       inside_boundary );
        effectiveCohesion = _GALEDruckerPrager_EffectiveCohesion(self,materialPoint,
                                                             inside_boundary);

  if(dim==2)
    {
      /* effectiveFrictionCoefficient=tan(phi).  If
         factor=sin(atan(1/tan(phi))) =>
         factor=cos(phi)=1/sqrt(1+tan(phi)**2) */
      factor=1/sqrt(1 + effectiveFrictionCoefficient*effectiveFrictionCoefficient);
      frictionalStrength = effectiveFrictionCoefficient*pressure*factor
        + effectiveCohesion*factor;
    }
  else
    {
      double cos_phi, sin_phi;
      /* cos(phi)=1/sqrt(1+tan(phi)**2) */
      cos_phi=
        1/sqrt(1 + effectiveFrictionCoefficient*effectiveFrictionCoefficient);
      sin_phi=effectiveFrictionCoefficient*cos_phi;
      factor=2*cos_phi/(sqrt(3.0)*(3-sin_phi));

      /* The full expression is

         sqrt(J2)=p*2*sin(phi)/(sqrt(3)*(3-sin(phi)))
                  + C*6*cos(phi)/(sqrt(3)*(3-sin(phi)))

         Note the extra factor of 3 for cohesion */

      frictionalStrength = effectiveFrictionCoefficient*factor*pressure
        + effectiveCohesion*3*factor;
    }
  
  /* If the minimumYieldStress is not set, then use the
     effective cohesion.  Maybe it should be the modified
     effective cohesion, though that probably should not matter
     much. */
  minimumYieldStress = self->minimumYieldStress;
  if(minimumYieldStress==0.0)
    minimumYieldStress=effectiveCohesion;
  
  /* Make sure frictionalStrength is above the minimum */
  if ( frictionalStrength < minimumYieldStress*factor) 
    frictionalStrength = minimumYieldStress*factor;

  self->yieldCriterion = frictionalStrength;
  self->curFrictionCoef = effectiveFrictionCoefficient*factor;

  return frictionalStrength;
}