Pt2d<Fonc_Num> cPIF_Bilin::VirtualDist(Pt2d<Fonc_Num> aP,bool UsePC,int aKCam)
{
   ELISE_ASSERT(aKCam==0,"cPIF_Bilin do not handle KCam!=0!!");
   int aOffs = aKCam * 4;

   Pt2d<Fonc_Num> aP00 = mCornF[aOffs].PtF();
   Pt2d<Fonc_Num> aP10 = mCornF[aOffs+1].PtF();
   Pt2d<Fonc_Num> aP01 = mCornF[aOffs+2].PtF();

   Fonc_Num aPdsX = (aP10.x-aP.x) / (aP10.x-aP00.x);
   Fonc_Num aPdsY = (aP01.y-aP.y) / (aP01.y-aP00.y);

   return    FDist(Pt2di(0,0)).mPtF.mul(aPdsX     * aPdsY    )
          +  FDist(Pt2di(1,0)).mPtF.mul((1-aPdsX) * aPdsY    )
          +  FDist(Pt2di(0,1)).mPtF.mul(aPdsX     * (1-aPdsY))
          +  FDist(Pt2di(1,1)).mPtF.mul((1-aPdsX) * (1-aPdsY))  ;

/*
    return     mFVDist[0].mPtF.mul(mPds[0+aOffs].FN())
            +  mFVDist[1].mPtF.mul(mPds[1+aOffs].FN())
            +  mFVDist[2].mPtF.mul(mPds[2+aOffs].FN())
            +  mFVDist[3].mPtF.mul(mPds[3+aOffs].FN());
*/
}
void USwFMOD::Update( FPointRegion Region, FCoords& Coords )
{
	guard(USwFMOD::Update);
	FMOD_RESULT result;
	//SWF_LOG( NAME_DevSound, TEXT("%s >> %s :: [%s],[%s]"), SWF_PLOG, *ToStr(Region), *ToStr(Coords) );

	if( !Viewport || !Viewport->IsValid() || !Viewport->Actor || !Viewport->Actor->IsValid() )
		return;

	// Load geometry
	if( bOcclusion )
	{
		static ULevel* level = NULL;
		if( Viewport->Actor->GetLevel() != level )
		{
			level = Viewport->Actor->GetLevel();
			LoadGeometry();
		}
	}

	// Time passes...
	DOUBLE DeltaTime = appSeconds() - LastTime;
	LastTime += DeltaTime;
	DeltaTime = Clamp( DeltaTime, 0.0, 1.0 );

	// Get viewactor
	AActor* ViewActor = Viewport->Actor->ViewTarget ? Viewport->Actor->ViewTarget : Viewport->Actor;
	
	// Is viewport realtime ?
	UBOOL Realtime = Viewport->IsRealtime() && Viewport->Actor->Level->Pauser == TEXT("");
	
	// Default viewport coords
	FVector location = FVector(0,0,0);
	FVector velocity = FVector(0,0,0);
	FVector forward = FVector(1,0,0);
	FVector up = FVector(0,0,1);


	//
	// Update listener
	//
	guard(USwFMODAudio::Update::UpdateListener);

	// Use ViewActor coords
	FCoords coords = GMath.UnitCoords / ViewActor->Rotation;;
	coords.Origin = ViewActor->Location;

	// Set viewport coords
	location = coords.Origin;
	velocity = ViewActor->Velocity;
	forward = coords.XAxis;
	up = coords.ZAxis;

	// verify
	SWF_VERIFY_FVECTOR(location);
	SWF_VERIFY_FVECTOR(velocity);
	SWF_VERIFY_FVECTOR_NORMAL(forward);
	SWF_VERIFY_FVECTOR_NORMAL(up);

	// Default listener coords
	FMOD_VECTOR fm_pos = {0,0,0};
	FMOD_VECTOR fm_vel = {0,0,0};
	FMOD_VECTOR fm_fwd = {0,0,1};
	FMOD_VECTOR fm_up  = {0,1,0};

	// Set listener coords
	fm_pos = ToFMODVector(location);
	fm_vel = ToFMODVector(velocity);
	fm_fwd = ToFMODNormal(forward);
	fm_up = ToFMODNormal(up);

	// verify
	SWF_VERIFY_FMODVECTOR(fm_pos);
	SWF_VERIFY_FMODVECTOR(fm_vel);
	SWF_VERIFY_FMODVECTOR_NORMAL(fm_fwd);
	SWF_VERIFY_FMODVECTOR_NORMAL(fm_up);

	// Update
	SWF_FMOD_CALL( System->set3DListenerAttributes( 0, &fm_pos, &fm_vel, &fm_fwd, &fm_up ) );
	unguard;


	//
	// Zone effects
	//
	guard(USwFMODAudio::Update::UpdateZone);

	/*// Default zone properties
	UBOOL bWaterZone = 0;
	UBOOL bReverbZone = 0;
	UBOOL bRaytraceReverb = 0;
	BYTE MasterGain = 100;
	INT CutoffHz = 6000;
	BYTE Delay[6] = {20,34,0,0,0,0};
	BYTE Gain[6] = {150,70,0,0,0,0};

	// Get zone properties
	if( Region.Zone && Region.Zone->IsValid() )
	{
		bWaterZone = Region.Zone->bWaterZone;
		bReverbZone = Region.Zone->bReverbZone;
		bRaytraceReverb = Region.Zone->bRaytraceReverb;
		MasterGain = Region.Zone->MasterGain;
		CutoffHz = Region.Zone->CutoffHz;
		appMemcpy(Delay, Region.Zone->Delay, 6*sizeof(BYTE));
		appMemcpy(Gain, Region.Zone->Gain, 6*sizeof(BYTE));
	}*/
	unguard;



	//
	// Update sounds.
	//
	guard(USwFMODAudio::Update::UpdateSounds);

	// Iterate through all channels
	for( FSwChannelEnumerator it(System); it; ++it )
	{
		FMOD::Channel* channel = *it;
		if( !IsChannelValid(channel) )
			continue;

		// Channel data
		FMOD::Sound* sample = GetChannelSample(channel);
		if( !sample )
			continue;

		UObject* object = GetSampleObject(sample);
		if( !object )
			continue;
		USound* sound = Cast<USound>(object);

		FSwSoundId id = GetChannelId(channel);
		AActor* actor = id.GetActor();

		FMOD_MODE fmode;
		SWF_FMOD_CALL( channel->getMode(&fmode) );
		UBOOL bIs3D = HasFlag(fmode,FMOD_3D);

		// Sample defaults
		FLOAT deffrequency;
		FLOAT defvolume;
		FLOAT defpanning;
		INT defpriority;
		SWF_FMOD_CALL( sample->getDefaults( &deffrequency, &defvolume, &defpanning, &defpriority ) );
	

		if( sound )
		{
			if( actor && actor->IsValid() )
			{
				// Ambient sounds
				if( id.GetSlot() == SLOT_Ambient )
				{
					if(	actor->AmbientSound != sound
					||	FDist(location, actor->Location) > actor->WorldSoundRadius() + AmbientHysteresis
					||  !Realtime )
					{
						// Stop ambient sound
						//SWF_LOG( NAME_DevSound, TEXT("%s -- %s :: Ambient OUT [%d]"), SWF_PLOG, *ToStr(id) );
						SWF_FMOD_CALL( channel->setUserData(NULL) );
						SWF_FMOD_CALL( channel->stop() );
						continue;
					}
					else
					{
						// Update ambient sound properties.
						FLOAT volume = actor->SoundVolume / 255.0f;
						FLOAT frequency = (actor->SoundPitch / 64.0f) * deffrequency;

						SWF_VERIFY_FLOAT(volume);
						SWF_VERIFY_FLOAT(frequency);

						SWF_FMOD_CALL( channel->setVolume( volume ) );
						SWF_FMOD_CALL( channel->setFrequency( frequency ) );

						if( bIs3D )
						{
							// Update 3D sound properties
							FLOAT mindist = ToFMODFloat(DistanceMin);
							FLOAT radius = ToFMODFloat( actor->WorldSoundRadius() );
							TSwSortMinMax( mindist, radius );

							SWF_VERIFY_FLOAT(radius);
							SWF_VERIFY_FLOAT(mindist);

							SWF_FMOD_CALL( channel->set3DMinMaxDistance( mindist, radius ) );
						}
					}
				}

				if( bIs3D )
				{
					// Update 3D sound properties
					FMOD_VECTOR snd_pos = ToFMODVector(actor->Location);
					FMOD_VECTOR snd_vel = ToFMODVector(actor->Velocity);
			
					SWF_VERIFY_FMODVECTOR(snd_pos);							
					SWF_VERIFY_FMODVECTOR(snd_vel);

					SWF_FMOD_CALL( channel->set3DAttributes(&snd_pos, &snd_vel) );
				}
			}
		}
	}
	unguard;


	//
	// Play ambient sounds
	//
	if( Realtime )
	{
		guard(USwFMODAudio::Update::PlayAmbient);
		for( INT i=0; i<Viewport->Actor->GetLevel()->Actors.Num(); ++i )
		{
			AActor* Actor = Viewport->Actor->GetLevel()->Actors(i);
			if(	Actor
			&&	Actor->AmbientSound
			&&	FDist(location, Actor->Location) <= Actor->WorldSoundRadius() )
			{
				FSwSoundId ambientid = FSwSoundId(Actor,SLOT_Ambient,0);
				//SWF_LOG( NAME_DevSound, TEXT("%s -- %s :: Ambient TEST IN [%s]"), SWF_PLOG, *ToStr(ambientid) );

				// Find this sound in currently playing ones
				FMOD::Channel* ambientchannel = NULL;
				for( FSwChannelEnumerator it(System,AmbientChannels); it; ++it )
				{
					FMOD::Channel* channel = *it;
					if( IsChannelValid(channel) && GetChannelId(channel) == ambientid )
					{
						//SWF_LOG( NAME_DevSound, TEXT("%s -- %s :: Ambient FOUND IN [%s]"), SWF_PLOG, *ToStr(GetChannelId(channel)) );
						ambientchannel = channel;
						break;
					}
				}

				// If not found play ambient
				if( !ambientchannel )
				{
					//SWF_LOG( NAME_DevSound, TEXT("%s -- %s :: Ambient PLAY IN [%s][%s]"), SWF_PLOG, *ToStr(ambientid), *ToStr(Actor->AmbientSound) );
					PlaySound( Actor, ambientid.GetId(), Actor->AmbientSound, Actor->Location, Actor->SoundVolume/255.0f, Actor->WorldSoundRadius(), Actor->SoundPitch/64.0f );
				}
			}
		}
		unguard;
	}
	

	//
	// Music
	//
	guard(UpdateMusic)

/*	REQUIREMENTS

	SongSection is updated at realtime by audio sys
	MTRAN_Fade* only fade out, not in
	music changes caused by transition only
	ttransition reset on change
	MTRAN_None = don't change
	MTRAN_Instant = instant change
	MTRAN_Segue = seamless?
	MTRAN_Fade = 1s fade
	MTRAN_FastFade = 1/3s fade
	MTRAN_SlowFade = 5s fade
*/
	// find music channel
	FMOD::Channel* musicchannel = NULL;
	for( FSwChannelEnumerator it(System,MusicChannels); it; ++it )
	{
		FMOD::Channel* channel = *it;
		if( !IsChannelValid(channel) )
			continue;

		if( !musicchannel )
		{
			musicchannel = channel;
		}
		else
		{
			// there can be only one music
			SWF_LOG( NAME_DevSound, TEXT("%s :: %s :: StopMusic %s"), SWF_PLOG, *PrintChannel(channel) );
			SWF_FMOD_CALL( channel->setUserData(NULL) );
			SWF_FMOD_CALL( channel->stop() );
		}
	}

	if( Viewport->Actor->Transition != MTRAN_None )
	{
		// init fading
		if( MusicFade < 0 )
		{
			SWF_LOG( NAME_DevSound, TEXT("%s :: %s :: Music transition %s S:%s T:%s "), SWF_PLOG
				, *ToStr(Viewport->Actor->Song)
				, *ToStr(Viewport->Actor->SongSection)
				, *ToStr(Viewport->Actor->Transition));

			switch( Viewport->Actor->Transition )
			{
				case MTRAN_Instant:		MusicFadeTime = -1.0f;	break;	// Instant
				case MTRAN_Segue:		MusicFadeTime = -1.0f;			// Instant precached
					if( Viewport->Actor->Song && !Viewport->Actor->Song->Handle )
						RegisterMusic(Viewport->Actor->Song);
					break;
				case MTRAN_Fade:		MusicFadeTime = 1.0f;	break;	// 1s fadeout
				case MTRAN_FastFade:	MusicFadeTime = 0.33f;	break;	// 1/3s fadeout
				case MTRAN_SlowFade:	MusicFadeTime = 5.0f;	break;	// 5s fadeout
				default:				MusicFadeTime = -1.0f;	break;	// Unknown,instant
					
			}
			MusicFade = MusicFadeTime;
		}

		// deduct delta
		MusicFade -= DeltaTime;
		//SWF_LOG( NAME_DevSound, TEXT("%s << %s :: MusicFade %s %s"), SWF_PLOG, *ToStr(MusicFade), *ToStr(MusicFadeTime) );

		if( MusicFade > 0 )
		{
			// fade volume
			if( musicchannel && MusicFadeTime > 0 )
			{
				SWF_FMOD_CALL( musicchannel->setVolume( MusicFade / MusicFadeTime) );
			}
		}
		else
		{
			// play new
			MusicFade = -1;
			Viewport->Actor->Transition = MTRAN_None;
			PlayMusic( Viewport->Actor->Song, musicchannel, Viewport->Actor->SongSection, Viewport->Actor->CdTrack, static_cast<EMusicTransition>(Viewport->Actor->Transition) );
		}
	}
	else
	{
		// Update section
		if( musicchannel )
		{
			// update section
			// FIXME:: getPosition doesn't work with volume 0 (virtual?)
			UINT sec = 0;
			result = musicchannel->getPosition(&sec,FMOD_TIMEUNIT_MODORDER);
			if( result == FMOD_OK )
			{
				Viewport->Actor->SongSection = sec;
			}

			// Update position
			if( IsChannelValid(musicchannel) )
			{
				UINT row = 0;
				result = musicchannel->getPosition(&row,FMOD_TIMEUNIT_MODROW);
				if( result == FMOD_OK )
				{
					// IT/MOD/XM
					UINT pattern = 0;
					result = musicchannel->getPosition(&pattern,FMOD_TIMEUNIT_MODPATTERN);
					if( result == FMOD_OK )
					{
						MusicPositions(Viewport->Actor->SongSection).row = row;
						MusicPositions(Viewport->Actor->SongSection).pattern = pattern;
					}
				}
				else
				{
					// MPEG/OGG
					UINT ms = 0;
					result = musicchannel->getPosition(&ms,FMOD_TIMEUNIT_MS);
					if( result == FMOD_OK )
					{
						MusicPositions(Viewport->Actor->SongSection).ms = ms;
					}
				}
			}
		}
		else if( Viewport->Actor->Song && VolumeMusic > 0 )
		{
			// Restart missing/dropped song (bad channel priorities?)
			SWF_LOG( NAME_DevSound, TEXT("%s :: %s :: Restarting missing song %s S:%s T:%s "), SWF_PLOG
				, *ToStr(Viewport->Actor->Song)
				, *ToStr(Viewport->Actor->SongSection)
				, *ToStr(Viewport->Actor->Transition));
			Viewport->Actor->Transition = MTRAN_Instant;
		}
	}



	unguard;

	// Update FMOD
	guard(UpdateFMOD);
	SWF_FMOD_CALL( System->update() );
	unguard;

	//SWF_LOG( NAME_DevSound, TEXT("%s << %s :: [%s],[%s]"), SWF_PLOG, *ToStr(Region), *ToStr(Coords) );
	unguard;
}
Exemple #3
0
UBOOL FExecHook::Exec( const TCHAR* Cmd, FOutputDevice& Ar )
{
    if( ParseCommand(&Cmd,TEXT("ShowLog")) )
    {
        if( GLogWindow )
        {
            GLogWindow->Show(1);
            SetFocus( *GLogWindow );
            GLogWindow->Display.ScrollCaret();
        }
        return TRUE;
    }
    else if( ParseCommand(&Cmd,TEXT("TakeFocus")) )
    {
        TObjectIterator<UEngine> EngineIt;
        if( EngineIt && EngineIt->Client && EngineIt->Client->Viewports.Num() )
        {
            SetForegroundWindow( (HWND)EngineIt->Client->Viewports(0)->GetWindow() );
        }
        return TRUE;
    }
    else if( ParseCommand(&Cmd,TEXT("EditActor")) )
    {
        UClass* Class;
        TObjectIterator<UEngine> EngineIt;
        if( EngineIt && ParseObject<UClass>( Cmd, TEXT("Class="), Class, ANY_PACKAGE ) )
        {
            const AActor* Player  = EngineIt->Client ? EngineIt->Client->Viewports(0)->Actor : NULL;
            const AActor* Found   = NULL;
            FLOAT   MinDist = 999999.0f;
            for( TObjectIterator<AActor> It; It; ++It )
            {
                FLOAT Dist = Player ? FDist(It->Location,Player->Location) : 0.0f;
                if( (!Player || It->GetLevel()==Player->GetLevel()) &&  (!It->bDeleteMe) && (It->IsA( Class) ) && (Dist<MinDist) )
                {
                    MinDist = Dist;
                    Found   = *It;
                }
            }
            if( Found )
            {
                WObjectProperties* P = new WObjectProperties( TEXT("EditActor"), 0, TEXT(""), NULL, 1 );
                P->OpenWindow( (HWND)EngineIt->Client->Viewports(0)->GetWindow() );
                P->Root.SetObjects( (UObject**)&Found, 1 );
                P->Show(1);
            }
            else Ar.Logf( TEXT("Actor not found") );
        }
        else Ar.Logf( TEXT("Missing class") );
        return TRUE;
    }
    else if( ParseCommand(&Cmd,TEXT("HideLog")) )
    {
        if( GLogWindow )
        {
            GLogWindow->Show(0);
        }
        return TRUE;
    }
    else if( ParseCommand(&Cmd,TEXT("Preferences")) && !GIsClient )
    {
        if( !m_pPreferences )
        {
            m_pPreferences = new WConfigProperties( TEXT("Preferences"), LocalizeGeneral("AdvancedOptionsTitle",TEXT("Window")) );
            m_pPreferences->SetNotifyHook( this );
            m_pPreferences->OpenWindow( GLogWindow ? GLogWindow->hWnd : NULL );
            m_pPreferences->ForceRefresh();
        }
        assert(m_pPreferences);
        m_pPreferences->Show(TRUE);
        SetFocus( *m_pPreferences );
        return TRUE;
    }
    return FALSE;
}
cPIF_Bilin::cPIF_Bilin(cCamStenopeBilin *aCSB,cSetEqFormelles & aSet):
    cParamIntrinsequeFormel (false,aCSB,aSet,true),
    mSet                    (aSet),
    mFiged                  (false),
    mDistInit               (aCSB->DBL()),
    mDistCur                (aCSB->DBL()),
    mCurPIF                 (0),
    mFVDist                 (1+mDistCur.Nb().y),
    mQuads                  (mDistCur.Nb().y),
    mLastCase               (-1,-1)
{
    AllowUnsortedVarIn_SetMappingCur = true;
    SetFocFree(true);
    SetPPFree(true);
 
    for (int aK=0 ; aK<4 ; aK++)
    {
        mCornF.push_back(cP2d_Etat_PhgrF(std::string("Pts")+ToString(aK)));
    }

    int aCpt=0;
    // Pour initier dans unr ordre ou le premri quadrangle passe d'abord
    for (int aKD8=0 ; aKD8<=ElMax(mDistCur.Nb().y,mDistCur.Nb().x) ; aKD8++)
    {
        for (int aKY=0; aKY<=mDistCur.Nb().y ; aKY++)
        {
            for (int aKX=0; aKX<=mDistCur.Nb().x ; aKX++)
            {
                if (ElMax(aKX,aKY)==aKD8)
                {
                    if (aKY == (mDistCur.Nb().y/2))
                    {
                        if (aKX==0)
                           mIndFrozen0 = 2 * aCpt;
                        if (aKX==mDistCur.Nb().x)
                           mIndFrozen1 = 2 * aCpt;
                    }
                    cIncIntervale anInt(false,NameInterv(Pt2di(aKX,aKY)),aSet,2);
                // anInt.Close();
                    cSomBilin aSB(mSet,mDistCur.Dist(Pt2di(aKX,aKY)),anInt);
                // aSB.mPtF = mSet.Alloc().NewPt2(mDistCur.Dist(Pt2di(aKX,aKY)));
                    mFVDist[aKY].push_back(aSB);
                    aCpt++;
                // mFVDist.push_back(mSet.Alloc().NewPt2(mDistCur.Dist(Pt2di(aKX,aKY))));
                }
            }
        }
    }

    Pt2di aC;
    for (aC.y=0; aC.y<mDistCur.Nb().y ; aC.y++)
    {
        for (aC.x=0; aC.x<mDistCur.Nb().x ; aC.x++)
        {
             cIncIntervale  anI00(FDist(aC+CamBilinCorn[0]).mInterv,NameInterv(CamBilinCorn[0]));
             cIncIntervale  anI10(FDist(aC+CamBilinCorn[1]).mInterv,NameInterv(CamBilinCorn[1]));
             cIncIntervale  anI01(FDist(aC+CamBilinCorn[2]).mInterv,NameInterv(CamBilinCorn[2]));
             cIncIntervale  anI11(FDist(aC+CamBilinCorn[3]).mInterv,NameInterv(CamBilinCorn[3]));

             mQuads[aC.y].push_back(cQuadrangle(anI00,anI10,anI01,anI11));
        }
    }

    NV_UpdateCurPIF();
}
Exemple #5
0
int main(int argc, char* argv[]){
  int a = 0, i = 0, j = 0, nN = 0, nM = 0;
  t_Params tParams;
  t_Flows tFlows;
  double *adDists = NULL;
  int    numtasks, rank, rc; 
  int    offset, nA, nA0, nSize, nCount, nStart, nFinish, nTag = 1;
  int    nPackets = 0, nPacketSize = 0, nPacketCurr = 0;
  MPI_Status   status;
  double *adLookUp = NULL, *adFookUp = NULL;

  fflush(stdout);

  rc = MPI_Init(&argc,&argv);
  if (rc != MPI_SUCCESS) {
    printf ("Error starting MPI program. Terminating.\n");
    MPI_Abort(MPI_COMM_WORLD, rc);
  }

  MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  /*get command line params*/
  getCommandLineParams(&tParams, argc, argv);
  
  fflush(stdout);
  adLookUp = (double *) malloc(sizeof(double)*MAX_S*BINS);
  adFookUp = (double *) malloc(sizeof(double)*BINS*BINS);

  if(!adLookUp || !adFookUp)
    goto memoryError;

  if(rank == 0){ /*head node reads data*/
    char   szOutFile[MAX_LINE_LENGTH];
    FILE*  ofp = NULL;

    sprintf(szOutFile,"%s%s",tParams.szOutFileStub,SUFFIX);    

    initLookUp(&tParams,adLookUp);

    initFookUp(adFookUp, adLookUp);

    printf("%d: Read data\n", rank);
    readData(adLookUp, tParams.szDataFile, &tFlows, &tParams);
    
    /*sends it out to other nodes*/
    printf("%d: Broadcast data\n", rank);
    MPI_Bcast((void *) adLookUp, MAX_S*BINS, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    MPI_Bcast((void *) adFookUp, BINS*BINS, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    printf("%d: Broadcast flows\n", rank);

    broadcastFlows(&tFlows);
    
    /*do my bit*/
    nN = tFlows.nN; nM = tFlows.nM;

    /*allocate memory for whole dist matrix*/
    nSize = (nN*(nN - 1))/2;
    
    nA = (int) (floor(nSize / numtasks));

    nA0 = nA + (nSize % numtasks);

    adDists = (double *) malloc(nA*sizeof(double)); 
    if(!adDists)
      goto memoryError;

    ofp = fopen(szOutFile, "w");
    if(!ofp)
      goto fileError;

    fprintf(ofp, "%d\n",nN);
    nCount = 0;
    for(i = 0; i < nN; i++){
      for(j = 0; j < i; j++){
       
	double  dDist = FDist(adFookUp, &(tFlows.adF[i*nM]),&(tFlows.adF[j*nM]), &(tFlows.anF[i*nM]), 
			 &(tFlows.anF[j*nM]), tFlows.anLengths[i], tFlows.anLengths[j]);

	fprintf(ofp,"%.8e\n",dDist); 
	nCount++;
	if(nCount == nA0){
	  goto finish;
	}
      }
      fflush(ofp);
    }

  finish:
    nPackets = ((nA - 1)/MAX_PACKET_SIZE) + 1;

    for (i = 1; i < numtasks; i++){
      
      nPacketCurr = 0;
      for(j = 0; j < nPackets; j++){
       	
	if(j < nPackets - 1){
	  nPacketSize = MAX_PACKET_SIZE;
	}
	else{
	  nPacketSize = nA % MAX_PACKET_SIZE;
	}
	
	MPI_Recv((void *) (&adDists[nPacketCurr]), nPacketSize, 
		 MPI_DOUBLE, i, nTag, MPI_COMM_WORLD, &status);
	
	nPacketCurr += nPacketSize;
      }
      

      for(j = 0; j < nA; j++){	
	fprintf(ofp, "%.8e\n",adDists[j]); 
      }
    }
    
  }
  else{
    /* receive data*/

    MPI_Bcast((void *) adLookUp, MAX_S*BINS, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    MPI_Bcast((void *) adFookUp, BINS*BINS, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    printf("%d: Receive flows\n",rank); fflush(stdout);
    
    receiveFlows(&tFlows);

    printf("%d: Perform calculations\n",rank); fflush(stdout);

    /*allocate memory for my part of distance matrix*/
  /*allocate memory for whole dist matrix*/
    nN = tFlows.nN; nM = tFlows.nM;
    
    nSize = (nN*(nN - 1))/2;
    
    nA = (int) floor(nSize / numtasks);

    nA0 = nA + (nSize % numtasks);

    adDists = (double *) malloc(nA*sizeof(double)); 
    if(!adDists)
      goto memoryError;


    nCount = 0; nStart = nA0 + (rank - 1)*nA; nFinish = nA0 + rank*nA;
    
    for(i = 0; i < nN; i++){
      for(j = 0; j < i; j++){
	t_Align tAlign;
	double  dDist = 0.0;

	if(nCount >= nStart){

	  dDist = FDist(adFookUp, &(tFlows.adF[i*nM]),&(tFlows.adF[j*nM]), 
			   &(tFlows.anF[i*nM]), &(tFlows.anF[j*nM]), 
			   tFlows.anLengths[i], tFlows.anLengths[j]);
	  
	  adDists[nCount - nStart] = dDist;
	}	

  	nCount++;
	if(nCount == nFinish){
	    goto finish2;
	}
	
      }
    }
  
  finish2:
      
    nPackets = ((nA - 1)/MAX_PACKET_SIZE) + 1;
      
    nPacketCurr = 0;
    for(j = 0; j < nPackets; j++){
      if(j < nPackets - 1){
	nPacketSize = MAX_PACKET_SIZE;
      }
      else{
	nPacketSize = nA % MAX_PACKET_SIZE;
      }   

      //printf("Send %d %d %d\n",rank, nPacketCurr, nPacketSize);
      MPI_Send((void *) (&adDists[nPacketCurr]), nPacketSize, 
		 MPI_DOUBLE, 0, nTag, MPI_COMM_WORLD);
      nPacketCurr += nPacketSize;
    }

    if(nPacketCurr != nA){
      printf("Message error\n");
    }
  }
 
  /*free allocated memory*/
  if(rank == 0){
    free(tFlows.adData);
  }
  free(tFlows.adF);
  free(tFlows.anF);
  free(tFlows.anLengths);
  free(adDists);
  free(adLookUp);
  free(adFookUp);
  // Wait for everyone to stop   
  
  MPI_Barrier(MPI_COMM_WORLD);

  // Always use MPI_Finalize as the last instruction of the program

  MPI_Finalize();
  exit(EXIT_SUCCESS);

 fileError:
  fprintf(stderr, "Failed opening output file in main\n");
  fflush(stderr);
  exit(EXIT_FAILURE);

 memoryError:
  fprintf(stderr, "Failed allocating memory in main\n");
  fflush(stderr);
  exit(EXIT_FAILURE);
}