Beispiel #1
0
	void AddWrite( Bit32u regFull, Bit8u val ) {
		Bit8u regMask = regFull & 0xff;
		/*
			Do some special checks if we're doing opl3 or dualopl2 commands
			Although you could pretty much just stick to always doing opl3 on the player side
		*/
		//Enabling opl3 4op modes will make us go into opl3 mode
		if ( header.hardware != HW_OPL3 && regFull == 0x104 && val && (*cache)[0x105] ) {
			header.hardware = HW_OPL3;
		} 
		//Writing a keyon to a 2nd address enables dual opl2 otherwise
		//Maybe also check for rhythm
		if ( header.hardware == HW_OPL2 && regFull >= 0x1b0 && regFull <=0x1b8 && val ) {
			header.hardware = HW_DUALOPL2;
		}
		Bit8u raw = ToRaw[ regMask ];
		if ( raw == 0xff )
			return;
		if ( regFull & 0x100 )
			raw |= 128;
		AddBuf( raw, val );
	}
Beispiel #2
0
static int addWLenBuf(uint8_t **ppCur, uint32_t *pdwLeft, const uint8_t *pBuf, uint32_t dwBufLen, int iNetByteOrder)
{
	assert((ppCur && *ppCur));
	assert((pBuf));

	if (CK_U32_SOF(dwBufLen)) {
		return E_BAD_PARAM;
	}
	
	if (pdwLeft) {
		if (CK_U32_SOF(*pdwLeft)) {
			return E_BAD_PARAM;
		}

		if (*pdwLeft < sizeof(uint16_t) + dwBufLen) {
			return E_OVERFLOW;
		}
	}

	CHECK_RET(addWord(ppCur,pdwLeft, (uint16_t)dwBufLen, iNetByteOrder));

	return AddBuf(ppCur, pdwLeft, pBuf, dwBufLen);
}
Beispiel #3
0
void ScoreICMTrk(long part, double x0, double y0, double z0, double u, 
		 double v, double w, double lmax, double E, double wgt, 
		 long id)
{
  long icm, ntot, nmu0, nmu1, nmu2, nseg, surf, type, ptr, np, in0, in1;
  long idx, ng, ncross, icm0, icm1, idx0, idx1, ng0, ng1;
  long mua, mus, mua0, mus0, mua1, mus1; 
  long s0, s1, s2;
  double d, l, x, y, z, un0, vn0, wn0, un1, vn1, wn1, un2, vn2, wn2;
  double wgt0, wgt1, mu0, mu1, mu2;
  const double *params;
   
  /* Check mode */

  if ((long)RDB[DATA_ICM_CALC] == NO)
    return;

  /* Get sizes */
      
  ntot = (long)RDB[DATA_ICM_NG0];
  nmu0 = (long)RDB[DATA_ICM_NMU0];
  nmu1 = (long)RDB[DATA_ICM_NMU1];
  nmu2 = (long)RDB[DATA_ICM_NMU2];
  nseg = (long)RDB[DATA_ICM_NSEG];
  
  /* Get pointer to few-group structure */
  
  ptr = (long)RDB[DATA_ICM_PTR_ENE0];
  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
  
  /* Get few-group index */
  
  if ((ng = GridSearch(ptr, E)) < 0)
    return;

  /* Convert index */
	  
  ng = ntot - ng - 1;
  CheckValue(FUNCTION_NAME, "ng1", "", ng, 0, ntot - 1);

  /* Reset new data */

  icm1 = -1;
  idx1 = -1;
  mua1 = -1;
  mus1 = -1;
  ng1 = -1;
  wgt1 = -1;

  /* Loop over data */

  icm = (long)RDB[DATA_PTR_ICM0];
  while (icm > VALID_PTR)
    {
      /* Get original particle Albedo data */

      icm0 = (long)RDB[part + PARTICLE_ICM_PTR_ICM];
      idx0 = (long)RDB[part + PARTICLE_ICM_IDX];
      mua0 = (long)RDB[part + PARTICLE_ICM_MUA];
      mus0 = (long)RDB[part + PARTICLE_ICM_MUS];
      ng0 = (long)RDB[part + PARTICLE_ICM_G];
      wgt0 = RDB[part + PARTICLE_ICM_WGT];

      /* Get surface pointer */
      
      surf = (long)RDB[icm + ICM_PTR_SURF];
      CheckPointer(FUNCTION_NAME, "(surf)", DATA_ARRAY, surf);
	      
      /* Get surface type */
	      
      type = (long)RDB[surf + SURFACE_TYPE];

      /* Get number of parameters */
	      
      np = (long)RDB[surf + SURFACE_N_PARAMS];
	      
      /* Pointer to parameter list */
	      
      ptr = (long)RDB[surf + SURFACE_PTR_PARAMS];
      CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
      params = &RDB[ptr];

      /* Move to starting position */
      
      /* Toi ekstrapolointi lienee turhaa sen jälkeen kun */
      /* trackin.c:tä muutettiin 14.8.2014 / 2.1.22 */

      Die(FUNCTION_NAME, "HUOM!!!");
      x = x0 - 2.0*EXTRAP_L*u;
      y = y0 - 2.0*EXTRAP_L*v;
      z = z0 - 2.0*EXTRAP_L*w;

      /* Reset total distance and number of crossings */
      
      l = 0.0;
      ncross = 0;
      
      /* Get initial position */
      
      in0 = TestSurface(surf, x, y, z, NO, id);
      in1 = -1;

      /* Loop over all surfaces in track */

      while (l < lmax)
	{      
	  /* Get distance */

	  d = SurfaceDistance(surf, params, type, np, x, y, z, u, v, w, id);

	  /* Extrapolate */
	  
	  d = d + EXTRAP_L;

	  /* Update coordinates */
	  
	  x = x + d*u;
	  y = y + d*v;
	  z = z + d*w;
	  
	  /* Test position */
	  
	  in1 = TestSurface(surf, x, y, z, NO, id);

	  /* Check with maximum */
	  
	  if (l + d > lmax)
	    {
	      /* Go back to collision site (for debugging) */

	      x = x0 + lmax*u;
	      y = y0 + lmax*v;
	      z = z0 + lmax*w;

	      /* Cancel crossing */

	      in1 = in0;

	      /* Break loop */
	      
	      break;
	    }
	  else
	    {
	      /* Update distance */
	      
	      l = l + d;
	    }

	  /* Check if surface was crossed */

	  if (in0 != in1)
	    {
	      /* Add counter */

	      ncross++;

	      /* Get surface index */

	      if ((idx = ICMIdx(surf, x, y, z, &un0, &vn0, &wn0, &un1, &vn1, 
				&wn1, &un2, &vn2, &wn2)) > -1)
		{
		  /* Calculate cosines */

		  mu0 = un0*u + vn0*v + wn0*w;
		  mu1 = un1*u + vn1*v + wn1*w;
		  mu2 = un2*u + vn2*v + wn2*w;

		  /* Get bins */

		  ptr = (long)RDB[DATA_ICM_PTR_MU0];
		  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
		  s0 = SearchArray(&RDB[ptr], fabs(mu0), nmu0 + 1);
		  CheckValue(FUNCTION_NAME, "s0", "", s0, 0, nmu0 - 1);

		  ptr = (long)RDB[DATA_ICM_PTR_MU1];
		  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
		  s1 = SearchArray(&RDB[ptr], mu1, nmu1 + 1);
		  CheckValue(FUNCTION_NAME, "s1", "", s1, 0, nmu1 - 1);

		  ptr = (long)RDB[DATA_ICM_PTR_MU2];
		  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
		  s2 = SearchArray(&RDB[ptr], mu2, nmu2 + 1);
		  CheckValue(FUNCTION_NAME, "s2", "", s2, 0, nmu2 - 1);

		  /* Calculate asymmetric and symmetric part */

		  mua = s1;
		  mus = s0*nmu2 + s2;

		  /* Check direction */

		  if ((in0 == NO) && (in1 == YES))
		    {
		      /* Check bins */

		      CheckValue(FUNCTION_NAME, "idx", "(1)", idx, 0, 
				 nseg - 1);
		      CheckValue(FUNCTION_NAME, "mua", "(1)", mua, 0, 
				 nmu1 - 1);
		      CheckValue(FUNCTION_NAME, "mus", "(1)", mus, 0, 
				 nmu0*nmu2 - 1);
		      CheckValue(FUNCTION_NAME, "ng", "(1)", ng, 0, 
				 ntot - 1);
		      
		      /* Score inward current */

		      if (RDB[DATA_CYCLE_IDX] > RDB[DATA_CRIT_SKIP] - 1.0)
			{
			  ptr = (long)RDB[icm + ICM_RES_CURR0];
			  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
			  AddBuf(1.0, wgt, ptr, id, -1, idx, mua, mus, ng);
			}
		      
		      /* Put new data and reset weight */
		      
		      icm0 = icm;
		      idx0 = idx;
		      mua0 = mua;
		      mus0 = mus;
		      ng0 = ng;
		      wgt0 = 1.0;
		    }
		  else if ((in0 == YES) && (in1 == NO))
		    {
		      /* Check active cycles */
		      
		      if (RDB[DATA_CYCLE_IDX] > RDB[DATA_CRIT_SKIP] - 1.0)
			{
			  /* Check index, group and angular bins */
			  
			  if ((idx0 > -1) && (ng0 > -1) && (mua0 > -1) &&
			      (mus0 > -1))
			    {
			      /* Check bins */
			      
			      CheckValue(FUNCTION_NAME, "idx0", "(2)", idx0, 0, 
					 nseg - 1);
			      CheckValue(FUNCTION_NAME, "mua0", "(2)", mua0, 0, 
					 nmu1 - 1);
			      CheckValue(FUNCTION_NAME, "mus0", "(2)", mus0, 0, 
					 nmu0*nmu2 - 1);
			      CheckValue(FUNCTION_NAME, "ng0", "(2)", ng0, 0, 
					 ntot - 1);
			      CheckValue(FUNCTION_NAME, "idx", "(2)", idx, 0, 
					 nseg - 1);
			      CheckValue(FUNCTION_NAME, "mua", "(2)", mua, 0, 
					 nmu1 - 1);
			      CheckValue(FUNCTION_NAME, "mus", "(2)", mus, 0, 
					 nmu0*nmu2 - 1);

			      /* Score outward current */

			      ptr = (long)RDB[icm + ICM_RES_CC1];
			      CheckPointer(FUNCTION_NAME, "(ptr)", 
					   DATA_ARRAY, ptr);
			      AddBuf(1.0, wgt, ptr, id, -1, idx0, mua0, mus0,
				     ng0, idx, mua, mus, ng);

			      ptr = (long)RDB[icm + ICM_RES_CC2];
			      CheckPointer(FUNCTION_NAME, "(ptr)", 
					   DATA_ARRAY, ptr);
			      AddBuf(wgt0, wgt, ptr, id, -1, idx0, mua0, mus0,
				     ng0, idx, mua, mus, ng);
			    }
			  else if ((ng0 > -1) && (RDB[DATA_CYCLE_IDX] > 
						  RDB[DATA_CRIT_SKIP] + 20.0))
			    Warn(FUNCTION_NAME, "Problem in geometry?");
			}
		      
		      /* Reset values */
		      
		      icm0 = -1;
		      idx0 = -1;
		      mua0 = -1;
		      mus0 = -1;
		      ng0 = -1;
		      wgt0 = 1.0;
		    }
		}
	    }

	  /* Put previous position */
	  
	  in0 = in1;
	}
    
      /* Check if particle is in */

      if (in1 == YES)
	{
	  /* Update new values */

	  if (icm1 > VALID_PTR)
	    Die(FUNCTION_NAME, "Point (%E, %E, %E) is in multiple regions",
		x, y, z);
	  else
	    {
	      icm1 = icm0;
	      idx1 = idx0;
	      mua1 = mua0;
	      mus1 = mus0;
	      ng1 = ng0;
	      wgt1 = wgt0;
	    }

	  /* Check number of crossings */

	  if (ncross == 0)
	    {
	      /* Surface index cannot have changed */
	      
	      if (idx0 != (long)RDB[part + PARTICLE_ICM_IDX])
		Die(FUNCTION_NAME, "This is impossible");

	      /* No other crossings are possible, add to counter */
	      
	      ptr = (long)RDB[icm + ICM_BREAK_PTR_COUNT];
	      CheckPointer(FUNCTION_NAME, "(ptr)", PRIVA_ARRAY, ptr);
	      AddPrivateData(ptr, 1, id);

	      /* Break loop */

	      break;
	    }
	}
    
      /* Next */

      icm = NextItem(icm);
    }

  /* Store values */
  
  WDB[part + PARTICLE_ICM_PTR_ICM] = (double)icm1;
  WDB[part + PARTICLE_ICM_IDX] = (double)idx1;
  WDB[part + PARTICLE_ICM_MUA] = (double)mua1;
  WDB[part + PARTICLE_ICM_MUS] = (double)mus1;
  WDB[part + PARTICLE_ICM_G] = (double)ng1;
  WDB[part + PARTICLE_ICM_WGT] = wgt1;
}
Beispiel #4
0
void PulseDet(long part, long mat, double dE, double x0, double y0, double z0, 
	      double wgt0, long id)
{
  long det, loc0, loc1, idx, ptr, pts, hix, i;
  double Etot, wgt;

  /* Loop over detectors */

  det = (long)RDB[DATA_PTR_DET0];
  while (det > VALID_PTR)
    {
      /* Check type */
      
      if (((long)RDB[det + DET_PARTICLE] != PARTICLE_TYPE_GAMMA) || 
	  ((long)RDB[det + DET_PTR_SBINS] > VALID_PTR))
	{
	  /* Next detector */
      
	  det = NextItem(det);

	  /* Cycle loop */

	  continue;
	}

      /* Get pointer to response functions */

      loc0 = (long)RDB[det + DET_PTR_RBINS];
      CheckPointer(FUNCTION_NAME, "(loc0)", DATA_ARRAY, loc0);

      /* Check mt (no multiple reaction bins allowed) */

      if ((long)RDB[loc0 + DET_RBIN_MT] != MT_PHOTON_PULSE_HEIGHT)
	{
	  /* Next detector */

	  det = NextItem(det);

	  /* Cycle loop */

	  continue;
	}
	  
      /* Pointer to pulse data */

      loc1 = (long)RDB[loc0 + DET_RBIN_PTR_PULSE_DATA];
      CheckPointer(FUNCTION_NAME, "(loc1)", DATA_ARRAY, loc1);
      
      /* Get pointer to statistics */
	      
      pts = (long)RDB[det + DET_PTR_STAT];
      CheckPointer(FUNCTION_NAME, "(pts)", DATA_ARRAY, pts);

      /* Check call type */
      
      if (part == -1)
	{
	  /*******************************************************************/

	  /***** Called after last batch *************************************/

	  /* Loop over OpenMP threads */
		  
	  for (i = 0; i < (long)RDB[DATA_OMP_MAX_THREADS]; i++)
	    {
	      /* Retrieve stored energy and weight */
	      
	      Etot = GetPrivateData(loc1 + DET_PULSE_EDEP, i);
	      wgt = GetPrivateData(loc1 + DET_PULSE_WGT, i);
	      
	      /* Pointer to energy grid */
	      
	      if ((ptr = (long)RDB[det + DET_PTR_EGRID]) < VALID_PTR)
		idx = 0;
	      else
		{
		  /* Grid search */
		  
		  idx = GridSearch(ptr, Etot);
		}
	      
	      /* Check index */
	      
	      if (idx > -1)
		{
		  /* Score pulse */
		  
		  AddBuf(1.0, wgt, pts, i, -1, idx, 0);
		}
	      
	      /* Reset pulse data */
		  
	      PutPrivateData(loc1 + DET_PULSE_PHOTON_IDX, -1, i);
	      PutPrivateData(loc1 + DET_PULSE_EDEP, 0.0, i);
	      PutPrivateData(loc1 + DET_PULSE_WGT, -1.0, i);
	    }
	  
	  /***************************************************************/
	}
      else
	{
	  /*******************************************************************/

	  /***** Called from collision point *********************************/

	  /* Check particle pointer */

	  CheckPointer(FUNCTION_NAME, "(part)", DATA_ARRAY, part);
	  
	  /* Check bin (this is just to check that the collision is */
	  /* inside the detector, the index is not relevant here).  */
	  
	  if (DetBin(det, mat, x0, y0, z0, -INFTY, 0.0, id) < 0)
	    {
	      /* Next detector */

	      det = NextItem(det);

	      /* Cycle loop */
	      
	      continue;
	    }
	  
	  /* Get history index */

	  hix = (long)RDB[part + PARTICLE_HISTORY_IDX] + 1;
	  
	  /* Check index */
	  
	  if (hix == (long)GetPrivateData(loc1 + DET_PULSE_PHOTON_IDX, id))
	    {
	      /* Still same history, add to temporary storage */
	      
	      AddPrivateData(loc1 + DET_PULSE_EDEP, dE, id);

	      /* Compare weight */

	      if (wgt0 != GetPrivateData(loc1 + DET_PULSE_WGT, id))
		Die(FUNCTION_NAME, "Mismatch in weight");
	    }
	  else
	    {
	      /* New history, retrieve stored energy and weight */
	      
	      Etot = GetPrivateData(loc1 + DET_PULSE_EDEP, id);
	      wgt = GetPrivateData(loc1 + DET_PULSE_WGT, id);

	      /* Pointer to energy grid */
	      
	      if ((ptr = (long)RDB[det + DET_PTR_EGRID]) < VALID_PTR)
		idx = 0;
	      else
		{
		  /* Grid search */
		  
		  idx = GridSearch(ptr, Etot);
		}
	      
	      /* Check index */
	      
	      if (idx > -1)
		{
		  /* Score pulse */
		  
		  AddBuf(1.0, wgt, pts, id, -1, idx, 0);
		}
	      
	      /* Store new data */

	      PutPrivateData(loc1 + DET_PULSE_PHOTON_IDX, hix, id);
	      PutPrivateData(loc1 + DET_PULSE_EDEP, dE, id);
	      PutPrivateData(loc1 + DET_PULSE_WGT, wgt0, id);
	    }

	  /*******************************************************************/
	}
      
      /* Next detector */
      
      det = NextItem(det);
    }
}
Beispiel #5
0
void
FormState(int Q)
{

  int I, S, S1, X; 
  int qX, Q1, Q2;
  int A, B;
  State SP;
  Exp E, E1;

  IBuf = NULL;
  IMax = 0;
  STab = NULL;
  Ss = 0; 
  AddState(1, &Q);

  for (S = 0; S < Ss; S++) 
    {
      SP = &STab[S];
      for (Xs = 0, S1 = 0; S1 < SP->States; S1++) 
        PushQ(SP->SList[S1]);
      for (SP->Empty = 0, Is = 0, X = 0; X < Xs; X++)  {
        qX = XStack[X];
      EVALUATE:
        E = EquTab[qX].Value;
        switch (E->Tag)  {
        case SymX:
          AddBuf(E->Body.Leaf, MakeExp(-1, OneX));
          break;
        case OneX:
          SP->Empty = 1;
          break;
        case ZeroX:
          break;
        case OptX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, OrX, MakeExp(-1, OneX), E->Body.Arg[0]);
          goto EVALUATE;
        case PlusX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, AndX, Q1, MakeExp(-1, StarX, Q1));
          goto EVALUATE;
        case StarX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, OrX, MakeExp(-1, OneX), MakeExp(-1, PlusX, Q1));
          goto EVALUATE;
        case OrX:
          Q1 = E->Body.Arg[0];
          Q2 = E->Body.Arg[1];
          PushQ(Q1);
          PushQ(Q2);
          break;
        case AndX:
          Q1 = E->Body.Arg[0], Q2 = E->Body.Arg[1];
          E1 = EquTab[Q1].Value;
          switch (E1->Tag) {
          case SymX:
            AddBuf(E1->Body.Leaf, Q2);
            break;
          case OneX:
            EquTab[qX].Value = EquTab[Q2].Value;
            goto EVALUATE;
          case ZeroX:
            MakeExp(qX, ZeroX);
            break;
          case OptX:
            A = E1->Body.Arg[0];
            MakeExp(qX, OrX, Q2, MakeExp(-1, AndX, A, Q2));
            goto EVALUATE;
          case PlusX:
            A = E1->Body.Arg[0];
            MakeExp(qX, AndX, A, MakeExp(-1, OrX, Q2, qX));
            goto EVALUATE;
          case StarX:
            A = E1->Body.Arg[0];
            MakeExp(qX, OrX, Q2, MakeExp(-1, AndX, A, qX));
            goto EVALUATE;
          case OrX:
            A = E1->Body.Arg[0], B = E1->Body.Arg[1];
            MakeExp(qX, OrX,
                    MakeExp(-1, AndX, A, Q2), MakeExp(-1, AndX, B, Q2));
            goto EVALUATE;
          case AndX:
            A = E1->Body.Arg[0], B = E1->Body.Arg[1];
            MakeExp(qX, AndX, A, MakeExp(-1, AndX, B, Q2));
            goto EVALUATE;
          }
        }
      }
      while (Xs > 0) 
        PopQ();
      SP->Shifts = Is;
      SP->ShList = cl_malloc(sizeof *SP->ShList * Is);
      for (I = 0; I < Is; I++)  {
        int rhs_state = -1;
        SP->ShList[I].LHS = IBuf[I].LHS;
        rhs_state = AddState(IBuf[I].Size, IBuf[I].RHS);
        SP = &STab[S];        /* AddState() might have reallocated state table -> update pointer */
        SP->ShList[I].RHS = rhs_state;
      }
    }
  free(IBuf);
  IBuf = 0;
  Is = IMax = 0;
}
void* handle_tcp_client(void * arg)
{
	printf("handling tcp client\n");
	
	char *buffer = NULL;
	Header hdr;
	int received = -1;
	long sock = reinterpret_cast<long> (arg);
	/* Receive message */
	do {
	
		if ((received = recv(sock, &hdr, sizeof(Header), 0)) < 0) {
			printf("handle_tcp_client: no header");
			break;
		}
		printf("received = %d\n", received);
		if (received == 0) break;
		while (received < sizeof(Header)) {
			int next_rec;
			if ((next_rec = recv(sock, (char*) &hdr + received, sizeof(Header) - received, 0)) <= 0) {
				break;
			} else {
				usleep(100);
			}

			
			received += next_rec;
			printf("received part = %d\n", next_rec);
		}
		if (received < sizeof(Header)) break;
		for (int i=0; i < received; i++) printf("%02x ", (reinterpret_cast<char*> (&hdr))[i]);
		printf("\n");
		
		hdr.cookie = ntohs(hdr.cookie);
		hdr.id = ntohs(hdr.id);
		hdr.cmd = ntohs(hdr.cmd);
		hdr.len = ntohs(hdr.len);
		hdr.seq = ntohl(hdr.seq);
		
		printf("cookie=%x id=%d cmd=%d len=%d seq=%ld\n", hdr.cookie, hdr.id, hdr.cmd, (hdr.len), (hdr.seq))	;
	
	
		if ((hdr.id == 0 && hdr.cookie == OK_COOKIE) || (hdr.id < MAX_ID && hdr.cookie == session[hdr.id].cookie)) {
			printf("OK\n");
			if (hdr.len > 0) {
				buffer = (char*) malloc(hdr.len);
				if (buffer == NULL) {
					printf("out of memory\n");
					break;
				}
				for (received = 0; received < hdr.len; ) {
					int next_rec = recv(sock, buffer + received, hdr.len - received, 0);
					if (next_rec < 0) {
						printf("couldn't get all buffer\n");
						break;
					}
					received += next_rec;
				}
				if (received < hdr.len) break;
				printf("got payload\n");
			}
			if ((Cmds) hdr.cmd == E_STORE) {
				printf("adding len=%d\n", hdr.len);
				if (AddBuf(hdr.id, hdr.seq, buffer, hdr.len)) {
					free(buffer);
				}
				buffer = NULL;
			} else 
			if ((Cmds) hdr.cmd == E_GET) {
				printf("E_GET\n");
				if (buffer) {
					free(buffer);
					buffer = NULL;
				}
				if (SendBuf(hdr.id, hdr.seq, sock)) break;
			} else 
			if ((Cmds) hdr.cmd == E_STATUS) {
				if (hdr.len != sizeof(BUF_Status)) {
					printf("hdr.len != sizeof(BUF_Status)\n");
				} else {
					printf("E_STATUS\n");
					BUF_Status* status = (BUF_Status*) buffer;
					session[hdr.id].alert = ntohs(status->alert);
					session[hdr.id].last_access = time(NULL);
 				}
				if (buffer != NULL) {
					free(buffer);
					buffer = NULL;
				}
			} else
			if ((Cmds) hdr.cmd == E_CHECK) {
				Response r;
				BUF_R_Check c;
				printf("E_CHECK\n");
				time_t now = time(NULL);
				r.response = htons(E_R_CHECK);
				r.len = htons(sizeof(BUF_R_Check));
				c.alert = htons(session[hdr.id].alert);
				c.last_access_sec = htons((int) difftime(now, session[hdr.id].last_access));
				
				if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
				if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
			} else
			if ((Cmds) hdr.cmd == E_CREATE) {
				Response r;
				BUF_R_Create_Login c;
				time_t now = time(NULL);
				printf("E_CREATE\n");
				
				if (hdr.len != sizeof(BUF_Create_Login)) {
					printf("hdr.len != sizeof(BUF_Create_Login)\n");
				} else {
					BUF_Create_Login* status = (BUF_Create_Login*) buffer;
					char username[MAX_NAME_LEN];
					char password[MAX_NAME_LEN];
					strncpy(username, status->username, MAX_NAME_LEN);
					strncpy(password, status->password, MAX_NAME_LEN);
					username[MAX_NAME_LEN-1] = 0;
					password[MAX_NAME_LEN-1] = 0;
					bool done = false;
					for (int i = 0; i < MAX_ID; i++) {
						if (users[i].username[0] == 0 || !strcmp(users[i].username, username) || difftime(now, users[i].last_access) > 60*60*24) {
							strcpy(users[i].password, password);
							users[i].last_access = time(NULL);
							pthread_mutex_lock(&g_mutex);
							while (session[next_id].last_access != 0 && difftime(now, session[next_id].last_access) < 60) {
								next_id = (next_id + 1) & MAX_ID;
								usleep(1000);
								now = time(NULL);
							}
							int id = next_id;
							next_id	= (next_id + 1) % MAX_ID;
							pthread_mutex_unlock(&g_mutex);
							
							pthread_mutex_lock(&session[next_id].mutex);

							for (int i = 0; i < MAX_BUFS; i++) 
								if (session[id].buf[i] != NULL) {
									free(session[id].buf);
									session[id].buf[i] = NULL;
								}
							session[id].alert = 0;
							session[id].head = 0;
							session[id].tail = 0;
							session[id].last_access = time(NULL);
							session[id].cookie = (unsigned short) time(NULL);
							pthread_mutex_unlock(&session[id].mutex);
							Response r;
							BUF_R_Create_Login c;
							r.response = htons(E_R_CREATE);
							r.len = htons(sizeof(BUF_R_Create_Login));
							c.id = htons(id);
							c.cookie = htons(session[id].cookie);
							done = true;
							if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
							if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
							break;
							
						}
					}
					if (!done) {
						Response r;
						BUF_R_Create_Login c;
						r.response = htons(E_R_CREATE);
						r.len = htons(sizeof(BUF_R_Create_Login));
						c.id = htons(0xFFFF);
						c.cookie = htons(0xFFFF);
						if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
						if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
					}						
				}
			} else
			if ((Cmds) hdr.cmd == E_LOGIN) {
				Response r;
				BUF_R_Create_Login c;
				printf("E_LOGIN");
				if (hdr.len != sizeof(BUF_Create_Login)) {
					printf("hdr.len != sizeof(BUF_Create_Login)\n");
				} else {
					BUF_Create_Login* status = (BUF_Create_Login*) buffer;
					char username[MAX_NAME_LEN];
					char password[MAX_NAME_LEN];
					strncpy(username, status->username, MAX_NAME_LEN);
					strncpy(password, status->password, MAX_NAME_LEN);
					username[MAX_NAME_LEN-1] = 0;
					password[MAX_NAME_LEN-1] = 0;
					printf("username=%s, password=%d\n", username, password);
					bool done = false;
					Response r;
					BUF_R_Create_Login c;
					r.response = htons(E_R_LOGIN);
					r.len = htons(sizeof(BUF_R_Create_Login));
					c.id = htons(0xFFFF);
					c.cookie = htons(0xFFFF);
					
					for (int i = 0; i < MAX_ID; i++) {
						if (!strcmp(users[i].username, username)) {
							if (!strcmp(users[i].password, password)) {
								c.id = htons(users[i].id);
								c.cookie = htons(users[i].cookie);
								printf("found login\n");
								break;
							} else {
								printf("username ok password not=%s\n", users[i].password);
							}

						} else {
							printf("not username=%s\n", users[i].username);
						}

					}
					if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
					if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
				}						
			} else {
				printf("Unknown command\n");
				if (buffer) {
					free(buffer);
					buffer = NULL;
				}
			}

				
		}
	
	} while (1);
	close(sock);

	if (buffer != NULL) {
		free(buffer);
		buffer = NULL;
	}
	
	printf("client closed\n");
	pthread_exit( NULL );
}
void ScoreInterfacePower(double fissE, double wgt, double x, double y, 
			 double z, double t, long id)
{
  long loc0, loc1, ptr, ncol, idx, nz, nr, i, j, k, uni, na, nt, l;
  double zmin, zmax, x0, y0, r0, r, f, r2, phi;

  /* Check that interfaces are defined */

  if ((loc0 = (long)RDB[DATA_PTR_IFC0]) < VALID_PTR)
    return;

  /***************************************************************************/

  /***** Interface to thermal hydraulics *************************************/

  /* Get zone index */

  ptr = (long)RDB[DATA_PTR_ZONE_IDX];
  idx = (long)GetPrivateData(ptr, id);

  /* Loop over interfaces */

  while (loc0 > VALID_PTR)
    {
      /* Check flag and type */
      
      if (((long)RDB[loc0 + IFC_CALC_OUTPUT] == YES) &&
	  (((long)RDB[loc0 + IFC_TYPE] < IFC_TYPE_FUEP) || 
	   ((long)RDB[loc0 + IFC_TYPE] > IFC_TYPE_FPIP)))
	{
	  /* Get pointer to statistics */
		    
	  ptr = (long)RDB[loc0 + IFC_PTR_STAT];
	  CheckPointer(FUNCTION_NAME, "ptr", DATA_ARRAY, ptr);

	  /* Check type */

	  if ((long)RDB[loc0 + IFC_TYPE] == IFC_TYPE_TET_MESH)
	    {
	      /* Get collision number */
	      
	      ncol = (long)RDB[DATA_PTR_COLLISION_COUNT];
	      ncol = (long)GetPrivateData(ncol, id);
	  
	      /* Get pointer to tet cell (set in ifcpoint.c) */

	      if ((loc1 = TestValuePair(loc0 + IFC_PTR_PREV_COL_CELL, ncol, id))
		  > VALID_PTR)
		{
		  /* Get index to statistics and score */
		  
		  if ((i = (long)RDB[loc1 + IFC_TET_MSH_STAT_IDX]) > -1)
		    AddBuf1D(fissE, wgt, ptr, id, i);
		}
	    }
	  else
	    {
	      /* Other types, get axial boundaries and number of bins */
	      
	      zmin = RDB[loc0 + IFC_ZMIN];
	      zmax = RDB[loc0 + IFC_ZMAX];
	      nz = (long)RDB[loc0 + IFC_NZ];
	      nr = (long)RDB[loc0 + IFC_NR];
	      
	      /* Find region (toi z-tarkistus tarvitaan että indeksi menee */
	      /* alarajalla oikein) */

	      if ((z >= zmin) && (z < zmax))
		if ((loc1 = (long)RDB[loc0 + IFC_PTR_SCORE]) > VALID_PTR)
		  if ((loc1 = SeekList(loc1, IFC_SCORE_REG_IDX, idx, 
				       SORT_MODE_ASCEND)) > VALID_PTR)
		    {
		      /* Get stat index */
		      
		      i = (long)RDB[loc1 + IFC_SCORE_STAT_IDX];
		      CheckValue(FUNCTION_NAME, "i", "", i, 0, 
				 (long)RDB[loc0 + IFC_STAT_NREG]);
		      
		      /* Get pointer to output data */
		      
		      loc1 = (long)RDB[loc1 + IFC_SCORE_PTR_OUT];
		      CheckPointer(FUNCTION_NAME, "(loc1)", DATA_ARRAY, loc1);
		      
		      /* Calculate axial bin */
		      
		      j = (long)((z - zmin)/(zmax - zmin)*((double)nz));
		      CheckValue(FUNCTION_NAME, "j", "", j, 0, nz - 1);
		      
		      /* Get center coordinates and radius */
		      
		      x0 = RDB[loc1 + IFC_OUT_X0];
		      y0 = RDB[loc1 + IFC_OUT_Y0];
		      r0 = RDB[loc1 + IFC_OUT_R];
		      
		      /* Check for zero radius */
		      
		      if (r0 < ZERO)
			Die(FUNCTION_NAME, "Zero radius");		      
		      
		      /* Get square radius */
		      
		      r = (x - x0)*(x - x0) + (y - y0)*(y - y0);
		      
		      /* Calculate radial zone (typerä toi jälkimmäinen) */
		      
		      if ((f = r/r0/r0) > 1.0)
			Die(FUNCTION_NAME, 
			    "Point is not inside %E %E : %E %E : %E",
			    x, y, x0, y0, r0);
		      else if (f == 1.0)
			f = 0.999999;
		      
		      /* Index */
		      
		      k = (long)(f*nr);		      
		      CheckValue(FUNCTION_NAME, "k", "", k, 0, nr - 1);
		      
		      /* Score */
		      
		      AddBuf(fissE, wgt, ptr, id, -1, i, j, k);
		    }
	    }
	}
      
      /* Next interface */
      
      loc0 = NextItem(loc0);
    }

  /***************************************************************************/

  /***** Interface to fuel performance codes *********************************/

  /* Get collision universe */
  
  ptr = (long)RDB[DATA_PTR_COLLISION_UNI];
  uni = GetPrivateData(ptr, id);
  
  /* Check pointer */
  
  CheckPointer(FUNCTION_NAME, "(uni)", DATA_ARRAY, uni);
  
  /* Check pointer to interface */
  
  if ((loc1 = (long)RDB[uni + UNIVERSE_PTR_IFC_FUEP]) > VALID_PTR)
    {
      /* Get coordinates */
      
      ptr = RDB[uni + UNIVERSE_PTR_PRIVA_X];
      CheckPointer(FUNCTION_NAME, "(xptr)", PRIVA_ARRAY, ptr);
      x = GetPrivateData(ptr, id);
      
      ptr = RDB[uni + UNIVERSE_PTR_PRIVA_Y];
      CheckPointer(FUNCTION_NAME, "(yptr)", PRIVA_ARRAY, ptr);
      y = GetPrivateData(ptr, id);

      ptr = RDB[uni + UNIVERSE_PTR_PRIVA_Z];
      CheckPointer(FUNCTION_NAME, "(zptr)", PRIVA_ARRAY, ptr);
      z = GetPrivateData(ptr, id);

      ptr = RDB[uni + UNIVERSE_PTR_PRIVA_T];
      CheckPointer(FUNCTION_NAME, "(ptr)", PRIVA_ARRAY, ptr);
      t = GetPrivateData(ptr, id);

      /* Coordinate transformation to cold system */

      CoordExpans(loc1, &x, &y, &z, t, 1);

      /* Get the size of the statistics */
      
      ptr = (long)RDB[loc1 + IFC_FUEP_OUT_PTR_LIM];
      CheckPointer(FUNCTION_NAME, "(limptr)", DATA_ARRAY, ptr);

      nz = (long)RDB[ptr + FUEP_NZ];
      na = (long)RDB[ptr + FUEP_NA];
      nr = (long)RDB[ptr + FUEP_NR];
      nt = (long)RDB[ptr + FUEP_NT];

      /* Get pointer to axial output zones */

      ptr = (long)RDB[loc1 + IFC_FUEP_OUT_PTR_Z];
      CheckPointer(FUNCTION_NAME, "(zptr)", DATA_ARRAY, ptr);

      /* Find interval */	  

      i = SearchArray(&RDB[ptr], z, nz + 1);

      /* Check */

      if (i < 0)
	{
	  Warn(FUNCTION_NAME,"Outside of axial zone");
	  return;
	}

      /* Calculate angle */

      phi = PolarAngle(x, y);
	  
      /* Check phi */

      CheckValue(FUNCTION_NAME, "phi", "", phi, 0.0, 2.0*PI);

      /* Get pointer to angular output zones */

      ptr = (long)RDB[loc1 + IFC_FUEP_OUT_PTR_PHI];
      CheckPointer(FUNCTION_NAME, "(aptr)", DATA_ARRAY, ptr);

      /* Rotate if needed */

      if (phi > 2.0*PI+RDB[ptr])
	phi -= 2.0*PI;
      
      /* Find interval */

      j = SearchArray(&RDB[ptr], phi, na + 1);

      /* Check */

      if (j < 0)
	{
	  Warn(FUNCTION_NAME,"Outside of angular zone");
	  return;
	}

      /* Calculate square radius */

      r2 = x*x + y*y;

      /* Get pointer to radial output zones */

      ptr = (long)RDB[loc1 + IFC_FUEP_OUT_PTR_R2];
      CheckPointer(FUNCTION_NAME, "(rptr)", DATA_ARRAY, ptr);

      /* Find interval */
	  
      k = SearchArray(&RDB[ptr], r2, nr + 1);

      /* Check */

      if (k < 0)
	{
	  Warn(FUNCTION_NAME,"Outside of radial zone");
	  return;
	}

      /* Find time bin */

      ptr = (long)RDB[loc1 + IFC_FUEP_OUT_PTR_TB];
      CheckPointer(FUNCTION_NAME, "(TBptr)", DATA_ARRAY, ptr);

      /* Find bin*/

      l = SearchArray(&RDB[ptr], t, nt + 1);

      /* Check */

      if (l < 0)
	return;

      /* Score */

      ptr = (long)RDB[loc1 + IFC_FUEP_PTR_POWER];
      CheckPointer(FUNCTION_NAME, "(Pptr)", DATA_ARRAY, ptr);
      
      AddBuf(fissE, wgt, ptr, id, -1, i, j, k, l);
    }

  /***************************************************************************/
}
void ApplyGCSymmetries(long gcu)
{
  long ng, adf, ptr, surf, type, ns, nc, nmax, n, m, i, sym, mode;
  double *f, *f0, val, max;

  /* Check pointer to group constant universe */

  CheckPointer(FUNCTION_NAME, "(gcu)", DATA_ARRAY, gcu);

  /***************************************************************************/

  /***** Fluxes and currents in ADF's ****************************************/

  /* Reset maximum difference */

  max = 0.0;

  /* Get pointer to ADF structure and symmetry */
  
  if ((adf = (long)RDB[gcu + GCU_PTR_ADF]) > VALID_PTR)
    if ((sym = (long)RDB[adf + ADF_SYM]) > 0)
      {
	/* Get pointer to outer boundary surface */
	
	surf = (long)RDB[adf + ADF_PTR_SURF];
	CheckPointer(FUNCTION_NAME, "(surf)", DATA_ARRAY, surf);
	
	/* Get surface type */
	
	type = (long)RDB[surf + SURFACE_TYPE];
	
	/* Get number of surfaces and corners */
	
	ns = (long)RDB[adf + ADF_NSURF];
	CheckValue(FUNCTION_NAME, "ns", "", ns, 1, 6);
	
	nc = (long)RDB[adf + ADF_NCORN];
	CheckValue(FUNCTION_NAME, "nc", "", nc, 0, 6);
	
	/* Get number of energy groups */
	
	ng = (long)RDB[DATA_ERG_FG_NG];
	CheckValue(FUNCTION_NAME, "ng", "", ng, 1, 100000);
	
	/* Allocate memory for temporary arrays  */
	
	if (ns > nc)
	  {
	    f0 = (double *)Mem(MEM_ALLOC, ns, sizeof(double));
	    f = (double *)Mem(MEM_ALLOC, ns, sizeof(double));
	  }
	else
	  {
	    f0 = (double *)Mem(MEM_ALLOC, nc, sizeof(double));
	    f = (double *)Mem(MEM_ALLOC, nc, sizeof(double));
	  }

	/* Loop over parameters */
	
	for (i = 0; i < 11; i++)
	  {
	    /* Avoid compiler warning */
	    
	    ptr = -1;
	    nmax = 0;
	    mode = 0;
	    
	    /* Get pointer and set number of values */
	    
	    if (i == 0)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_HET_SURF_FLUX];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 1)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_HET_CORN_FLUX];
		nmax = nc;
		mode = 2;
	      }
	    else if (i == 2)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_SURF_IN_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 3)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_SURF_OUT_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 4)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_SURF_NET_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 5)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_MID_IN_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 6)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_MID_OUT_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 7)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_MID_NET_CURR];
		nmax = ns;
		mode = 1;
	      }
	    else if (i == 8)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_CORN_IN_CURR];
		nmax = nc;
		mode = 2;
	      }
	    else if (i == 9)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_CORN_OUT_CURR];
		nmax = nc;
		mode = 2;
	      }
	    else if (i == 10)
	      {
		ptr = RDB[gcu + GCU_RES_FG_DF_CORN_NET_CURR];
		nmax = nc;
		mode = 2;
	      }
	    else
	      Die(FUNCTION_NAME, "Overflow");
	    
	    /* Check pointer */
	    
	    if (ptr < VALID_PTR)
	      continue;
	    
	    /* Loop over energy groups */
	    
	    for (n = 0; n < ng; n++)
	      {
		/* Read data */
		
		for (m = 0; m < nmax; m++)
		  f0[m] = BufVal(ptr, m, n);
		
		/* Check geometry type */
		
		switch (type)
		  {
		  case SURF_SQC:
		  case SURF_RECT:
		    {
		      /* Infinite square prism (2D case) */
		      
		      if (sym == 1)
			{
			  /* Full symmetry */
			  
			  if (type == SURF_SQC)
			    {
			      /* Average over all values if sqc */

			      val = (f0[0] + f0[1] + f0[2] + f0[3])/4.0;
			      f[0] = val - f0[0];
			      f[1] = val - f0[1];
			      f[2] = val - f0[2];
			      f[3] = val - f0[3];
			    }
			  else
			    {
			      /* Average over NS and EW and all corners */
			      /* if rect */

			      if (mode == 1)
				{
				  val = (f0[S] + f0[N])/2.0;
				  f[S] = val - f0[S];
				  f[N] = val - f0[N];
				  val = (f0[W] + f0[E])/2.0;
				  f[W] = val - f0[W];
				  f[E] = val - f0[E];
				}
			      else
				{
				  val = (f0[0] + f0[1] + f0[2] + f0[3])/4.0;
				  f[0] = val - f0[0];
				  f[1] = val - f0[1];
				  f[2] = val - f0[2];
				  f[3] = val - f0[3];
				}
			    }
			}
		      else if (sym == 2)
			{
			  /* S1 / NS symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[S] + f0[N])/2.0;
			      f[W] = 0.0;
			      f[S] = val - f0[S];
			      f[E] = 0.0;
			      f[N] = val - f0[N];
			    }
			  else
			    {
			      val = (f0[NW] + f0[SW])/2.0;
			      f[NW] = val - f0[NW];
			      f[SW] = val - f0[SW];
			      val = (f0[NE] + f0[SE])/2.0;
			      f[NE] = val - f0[NE];
			      f[SE] = val - f0[SE];
			    }
			}
		      else if (sym == 3)
			{
			  /* C1 / SENW symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[W] + f0[S])/2.0;
			      f[W] = val - f0[W];
			      f[S] = val - f0[S];
			      val = (f0[E] + f0[N])/2.0;
			      f[E] = val - f0[E];
			      f[N] = val - f0[N];
			    }
			  else
			    {
			      val = (f0[SE] + f0[NW])/2.0;
			      f[SW] = 0.0;
			      f[SE] = val - f0[SE];
			      f[NW] = val - f0[NW];
			      f[NE] = 0.0;
			    }
			}
		      else if (sym == 4)
			{
			  /* S2 / EW symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[W] + f0[E])/2.0;
			      f[W] = val - f0[W];
			      f[S] = 0.0;
			      f[E] = val - f0[E];
			      f[N] = 0.0;
			    }
			  else
			    {
			      val = (f0[SW] + f0[SE])/2.0;
			      f[SW] = val - f0[SW];
			      f[SE] = val - f0[SE];
			      val = (f0[NW] + f0[NE])/2.0;
			      f[NW] = val - f0[NW];
			      f[NE] = val - f0[NE];
			    }
			}
		      else if (sym == 5)
			{
			  /* C2 / SWNE symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[W] + f0[N])/2.0;
			      f[W] = val - f0[W];
			      f[N] = val - f0[N];
			      val = (f0[E] + f0[S])/2.0;
			      f[E] = val - f0[E];
			      f[S] = val - f0[S];
			    }
			  else
			    {
			      val = (f0[SW] + f0[NE])/2.0;
			      f[SW] = val - f0[SW];
			      f[SE] = 0.0;
			      f[NW] = 0.0;
			      f[NE] = val - f0[NE];
			    }
			}
		      else if (sym != 0)
			Die(FUNCTION_NAME, "Invalid symmetry");
		      
		      /* Break case */
		      
		      break;
		    }
		  case SURF_HEXYC:
		  case SURF_HEXXC:
		    {
		      /* Infinite hexagonal prism (2D case) */
		      
		      if (sym == 1)
			{
			  /* Full symmetry */
			  
			  val = (f0[0] + f0[1] + f0[2] + 
				 f0[3] + f0[4] + f0[5])/6.0;
			  f[0] = val - f0[0];
			  f[1] = val - f0[1];
			  f[2] = val - f0[2];
			  f[3] = val - f0[3];
			  f[4] = val - f0[4];
			  f[5] = val - f0[5];
			}
		      else if (sym == 2)
			{
			  /* S1-symmetry */
			  
			  if (mode == 1)
			    {
			      f[0] = 0.0;
			      f[3] = 0.0;
			      val = (f0[1] + f0[5])/2.0;
			      f[1] = val - f0[1];
			      f[5] = val - f0[5];
			      val = (f0[2] + f0[4])/2.0;
			      f[2] = val - f0[2];
			      f[4] = val - f0[4];
			    }
			  else
			    {
			      val = (f0[0] + f0[5])/2.0;
			      f[0] = val - f0[0];
			      f[5] = val - f0[5];
			      val = (f0[1] + f0[4])/2.0;
			      f[1] = val - f0[1];
			      f[4] = val - f0[4];
			      val = (f0[2] + f0[3])/2.0;
			      f[2] = val - f0[2];
			      f[3] = val - f0[3];
			    }
			}
		      else if (sym == 3)
			{
			  /* C1-symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[0] + f0[1])/2.0;
			      f[0] = val - f0[0];
			      f[1] = val - f0[1];
			      val = (f0[2] + f0[5])/2.0;
			      f[2] = val - f0[2];
			      f[5] = val - f0[5];
			      val = (f0[3] + f0[4])/2.0;
			      f[3] = val - f0[3];
			      f[4] = val - f0[4];
			    }
			  else
			    {
			      f[0] = 0.0;
			      f[3] = 0.0;
			      val = (f0[1] + f0[5])/2.0;
			      f[1] = val - f0[1];
			      f[5] = val - f0[5];
			      val = (f0[2] + f0[4])/2.0;
			      f[2] = val - f0[2];
			      f[4] = val - f0[4];
			    }
			}
		      else if (sym == 4)
			{
			  /* S2-symmetry */
			  
			  if (mode == 1)
			    {
			      f[1] = 0.0;
			      f[4] = 0.0;
			      val = (f0[0] + f0[2])/2.0;
			      f[0] = val - f0[0];
			      f[2] = val - f0[2];
			      val = (f0[3] + f0[5])/2.0;
			      f[3] = val - f0[3];
			      f[5] = val - f0[5];
			    }
			  else
			    {
			      val = (f0[0] + f0[1])/2.0;
			      f[0] = val - f0[0];
			      f[1] = val - f0[1];
			      val = (f0[2] + f0[5])/2.0;
			      f[2] = val - f0[2];
			      f[5] = val - f0[5];
			      val = (f0[3] + f0[4])/2.0;
			      f[3] = val - f0[3];
			      f[4] = val - f0[4];
			    }
			}
		      else if (sym == 5)
			{
			  /* C2-symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[0] + f0[3])/2.0;
			      f[0] = val - f0[0];
			      f[3] = val - f0[3];
			      val = (f0[1] + f0[2])/2.0;
			      f[1] = val - f0[1];
			      f[2] = val - f0[2];
			      val = (f0[4] + f0[5])/2.0;
			      f[4] = val - f0[4];
			      f[5] = val - f0[5];
			    }
			  else
			    {
			      f[1] = 0.0;
			      f[4] = 0.0;
			      val = (f0[0] + f0[2])/2.0;
			      f[0] = val - f0[0];
			      f[2] = val - f0[2];
			      val = (f0[3] + f0[5])/2.0;
			      f[3] = val - f0[3];
			      f[5] = val - f0[5];
			    }
			}
		      else if (sym == 6)
			{
			  /* S3-symmetry */
			  
			  if (mode == 1)
			    {
			      f[2] = 0.0;
			      f[5] = 0.0;
			      val = (f0[1] + f0[3])/2.0;
			      f[1] = val - f0[1];
			      f[3] = val - f0[3];
			      val = (f0[0] + f0[4])/2.0;
			      f[0] = val - f0[0];
			      f[4] = val - f0[4];
			    }
			  else
			    {
			      val = (f0[0] + f0[3])/2.0;
			      f[0] = val - f0[0];
			      f[3] = val - f0[3];
			      val = (f0[1] + f0[2])/2.0;
			      f[1] = val - f0[1];
			      f[2] = val - f0[2];
			      val = (f0[4] + f0[5])/2.0;
			      f[4] = val - f0[4];
			      f[5] = val - f0[5];
			    }
			}
		      else if (sym == 7)
			{
			  /* C3-symmetry */
			  
			  if (mode == 1)
			    {
			      val = (f0[0] + f0[5])/2.0;
			      f[0] = val - f0[0];
			      f[5] = val - f0[5];
			      val = (f0[1] + f0[4])/2.0;
			      f[1] = val - f0[1];
			      f[4] = val - f0[4];
			      val = (f0[2] + f0[3])/2.0;
			      f[2] = val - f0[2];
			      f[3] = val - f0[3];
			    }
			  else
			    {
			      f[2] = 0.0;
			      f[5] = 0.0;
			      val = (f0[1] + f0[3])/2.0;
			      f[1] = val - f0[1];
			      f[3] = val - f0[3];
			      val = (f0[0] + f0[4])/2.0;
			      f[0] = val - f0[0];
			      f[4] = val - f0[4];
			    }
			}
		      else if (sym != 0)
			Die(FUNCTION_NAME, "Invalid symmetry");

		      /* Break case */
		      
		      break;
		    }
		  }

		/* Mark scoring buffer unreduced */

		WDB[DATA_BUF_REDUCED] = (double)NO;

		/* Get maximum difference for error checking */
		/* (surface flux and currents) */

		if ((i == 0) || (i == 2) || (i == 3))
		  for (m = 0; m < nmax; m++)
		    if (fabs(f[m]/f0[m]) > max)
		      max = fabs(f[m]/f0[m]);
		
		/* Put data */
		
		for (m = 0; m < nmax; m++)
		  AddBuf(f[m], 1.0, ptr, 0, -1, m, n);
		
		/* Reduce buffer */
		
		ReduceBuffer();
	      }
	  }
	
	/* Free temporary arrays */
  
	Mem(MEM_FREE, f0);
	Mem(MEM_FREE, f);
      }
  
  /* Print warning if statistics is good enough */
  
  if ((long)(RDB[DATA_MICRO_CALC_BATCH_SIZE]*RDB[DATA_CYCLE_BATCH_SIZE]) >
      1000*20)      
    if (max > 0.1)
      Note(0, "ADF symmetry option may be wrong");
  
  /***************************************************************************/
}