Exemple #1
0
void H2_3D_Tree::ComputeWeights(double *Tkz, int *Ktable, double *Kweights,
					double *Cweights, int n, double alpha, int use_chebyshev) {
	int i, k, m, l1, l2, l3, count, ncell, ninteract;
	double tmp1, tmp2;
	vector3 vtmp;
	
	double *nodes, *vec;
	vector3 *fieldt, *Sn;
	nodes = (double *)malloc(n * sizeof(double));
	vec   = (double *)malloc(n * sizeof(double));
	int n3 = n*n*n;                     // n3 = n^3
	int Nc = 2*n3;                      // Number of child Chebyshev nodes
	fieldt = (vector3 *)malloc(Nc * sizeof(vector3));
    // Chebyshev-transformed coordinates
	Sn     = (vector3 *)malloc(n * Nc * sizeof(vector3));
	//double pi = M_PI;
	
    // Initialize lookup table
	for (i=0;i<343;i++)
		Ktable[i] = -1;
    // Create lookup table
	ncell = 0;
	ninteract = 0;
	for (l1=-3;l1<4;l1++) {
		for (l2=-3;l2<4;l2++) {
			for (l3=-3;l3<4;l3++) {
				if (abs(l1) > 1 || abs(l2) > 1 || abs(l3) > 1) {
					Ktable[ncell] = ninteract;
					ninteract++;
				}
				ncell++;
			}
		}
	}

    // Compute the n Chebyshev nodes of T_n(x)
//	for (m=0; m<n; m++)
//		nodes[m] = cos(pi*((double)m+0.5)/(double)n);
    
    // Compute n Chebyshev nodes in [-.5, .5]
	CalculateNodeLocations(n,nodes,use_chebyshev);

    // Evaluate the Chebyshev polynomials of degree 0 to n-1 at the nodes
	for (m=0; m<n; m++) {
		ComputeTk(nodes[m],n,vec);
		i = m*n;
		for (k=0;k<n;k++) {
			Tkz[i+k] = vec[k];
        }
	}

    if (use_chebyshev) {
		// Compute the weights for the kernel matrix K
        count = 0;
        for (l1=0;l1<n;l1++) {
            tmp1 = 1./sqrt(1-nodes[l1]*nodes[l1]);
            for (l2=0;l2<n;l2++) {
                tmp2 = tmp1/sqrt(1-nodes[l2]*nodes[l2]);
                for(l3=0;l3<n;l3++) {
                    Kweights[count] = tmp2/sqrt(1-nodes[l3]*nodes[l3]);
                    count++;
                }
            }
        }
	}
	else {
        // Compute the weights for the kernel matrix K
        count = 0;
        for (l1=0;l1<n;l1++) {
            tmp1 = 1./sqrt(1-nodes[l1]*nodes[l1]);
            for (l2=0;l2<n;l2++) {
                tmp2 = tmp1/sqrt(1-nodes[l2]*nodes[l2]);
                for(l3=0;l3<n;l3++) {
                    Kweights[count] = 1; //tmp2/sqrt(1-nodes[l3]*nodes[l3]);
                    count++;
                }
            }
        }
	}
	// Map all Chebyshev nodes from the children cells to the parent
	k = 0;
    double scale = 1 / (1+alpha);
    //scale = 1;
	for (i=0;i<2;i++) {
        // Determine the mapping function for the specific child cell
		vtmp.x = -0.5;
		vtmp.y = -0.5;
		
		if (i == 0)
			vtmp.z = -0.5;
		else
			vtmp.z = 0.5;
		
		for (l1=0;l1<n;l1++) {
			for (l2=0;l2<n;l2++) {
				for (l3=0;l3<n;l3++) {
                    fieldt[k].x = nodes[l1] * .5 + vtmp.x * scale;
                    fieldt[k].y = nodes[l2] * .5 + vtmp.y * scale;
                    fieldt[k].z = nodes[l3] * .5 + vtmp.z * scale;
                    k++;
				}
			}
		}
	}

    
    // Compute Sc, the mapping function for the field points
	ComputeSn(fieldt,Tkz,n,Nc,Sn, use_chebyshev);
	
    // Extract out the Chebyshev weights
	count = 0;
	for (l1=0;l1<n;l1++) {
		k = l1*Nc;
		for (l2=0;l2<n;l2++) {
			Cweights[count] = Sn[k+l2].z;
			count++;
		}
	}
	for (l1=0;l1<n;l1++) {
		k = l1*Nc;
		for (l2=0;l2<n;l2++) {
			Cweights[count] = Sn[k+n3+l2].z;
			count++;
		}
	}
	free(nodes);
	free(vec);
	free(fieldt);
	free(Sn);
}
Exemple #2
0
void ComputeWeightsPBC(double *UpMat, int n, double alpha, double *Tkz) {

  int i, j, k, l, m, l1, l2, l3, count1, count2;
  vec3 vtmp;

  int n3 = n*n*n;  // n3 = n^3
  int n6 = n3*n3;  // n6 = n^6
  int Nc = 27*n3;  // Number of child Chebyshev nodes
  double nodes[n]; //, vec[n]; 
  vec3 fieldt[Nc]; // Chebyshev-transformed coordinates
  vec3 Sn[n*Nc];
	
  double pi    = M_PI;
  double third = 1.0/3.0; // the parent box is divided into three children in each dimension
	
  // Compute the n Chebyshev nodes of T_n(x)
  for (m=0;m<n;m++)
    nodes[m] = cos(pi*((double)m+0.5)/(double)n);

  // Map all Chebyshev nodes from the children cells to the parent
  k = 0;
  for (i=0;i<27;i++) {
    // Determine the mapping function for the specific child cell
    if (i<9) {
      vtmp.x = -2;			
      if (i<3) 
	vtmp.y = -2;
      else if (i<6)
	vtmp.y = 0;
      else
	vtmp.y = 2;
    } else if (i<18) {
      vtmp.x = 0;
      if (i<12)
	vtmp.y = -2;
      else if (i<15)
	vtmp.y = 0;
      else
	vtmp.y = 2;
    } else {
      vtmp.x = 2;
      if (i<21)
	vtmp.y = -2;
      else if (i<24)
	vtmp.y = 0;
      else
	vtmp.y = 2;
    }
    if (i%3 == 0)
      vtmp.z = -2;
    else if (i%3 == 1)
      vtmp.z = 0;
    else
      vtmp.z = 2;


    // Map all Chebyshev nodes from the children cells to the parent
    // Note: 'nodes' below corresponds to alpha=0
    // scaled child grids: nodes[i]*(1+alpha) +- 2
    // scaled parent box: (1+alpha)*6
    // ihalfL: 1/((1+alpha)*3)
    // so the relative position is: (nodes[i] +- 2/(1+alpha)) / 3
    double L = AdjustBoxSize(1.0, alpha);
    for (l1=0;l1<n;l1++) {
      for (l2=0;l2<n;l2++) {
	for (l3=0;l3<n;l3++) {
	  fieldt[k].x = (nodes[l1] + vtmp.x / L) * third;
	  fieldt[k].y = (nodes[l2] + vtmp.y / L) * third;
	  fieldt[k].z = (nodes[l3] + vtmp.z / L) * third;
	  k++;
	}
      }
    }
  }
    
  // Compute Sc, the mapping function for the field points
  ComputeSn(fieldt, Nc, Sn, n, Tkz, 1); // 1 for Chebyshev
	
  // Compute Sxyz, the weights for the sources
  double *Sxyz = (double *)malloc(n3 * Nc * sizeof(double));
  for (k=0;k<Nc;k++) {
    l = 0;
    for (l1=0;l1<n;l1++) {
      for (l2=0;l2<n;l2++) {
	for (l3=0;l3<n;l3++) {
	  Sxyz[l*Nc+k] = Sn[l1*Nc+k].x*Sn[l2*Nc+k].y*Sn[l3*Nc+k].z;
	  l++;
	}
      }
    }
  }


  // Accumulate the weights into a single weight matrix W
  double *W = (double *)calloc(n6, sizeof(double));
	
  for (i=0;i<27;i++) {
    count1 = 0;
    count2 = i*n3;
    for (j=0;j<n3;j++) {
      for (k=0;k<n3;k++) {
	W[count1] += Sxyz[k*Nc+count2]; // Notice the transpose here
	count1++;
      }
      count2++;
    }
  }
	
  UpMat = Assign(UpMat, W, n6);
   
  free(Sxyz);
  free(W);	
}