Exemple #1
0
void main()
{
  clrscr();
  vector v1, v2, v3;
  //vector v4 = {"vec 4", 3.5, 4.4, -2.3};
  vector *pv1, *pv2, *pv;

  pv1 = &v1;
  val_vec(pv1);
  clrscr();
  printvec1(pv1);
  getch();

  //strcpy(v1.nombre, "vec 1");
  //v1 = v4;

  //strcpy(v2.nombre, "vec 2");
  //v2.x = 5.5;
  //v2.y = 6.4;
  //v2.z = 0.3;

  /*
  printvec(v1);
  printf("\n");
  printvec(v2);
  getch();
  pv1 = &v1;
  pv2 = &v2;
  printvec1(pv1);
  printf("\n");
  printvec1(pv2);
  getch();*/

}//void main()
Exemple #2
0
int CompPhiUsingBorn(Vec &true_sol, FMMData &fmm_data){

  // Initialize and get data about the problem
  PetscErrorCode ierr;
  PetscInt       m,n,l, M,N,L;
  m=fmm_data.m; // local rows
  n=fmm_data.n; // local columns
  M=fmm_data.M; // global rows
  N=fmm_data.N; // global columns
  l=fmm_data.l; // local val vec length
  L=fmm_data.L; // global val vec length
  FMM_Tree_t *tree=fmm_data.tree;
  const MPI_Comm comm=*(tree->Comm());
  int cheb_deg=fmm_data.fmm_mat->ChebDeg();
  int omp_p=omp_get_max_threads();

  // Get nodes (I think that these are just the ones local to this compute node)
  std::vector<FMMNode_t*> nlist;
  { // Get non-ghost, leaf nodes.
    std::vector<FMMNode_t*>& nlist_=tree->GetNodeList();
    for(size_t i=0;i<nlist_.size();i++){
      if(nlist_[i]->IsLeaf() && !nlist_[i]->IsGhost()){
	nlist.push_back(nlist_[i]);
      }
    }
  }
  assert(nlist.size()>0);

  // Pointwise multiplication of \eta and \phi_0
  Vec prod;
  VecCreateMPI(comm,l,PETSC_DETERMINE,&prod);

  ierr = VecPointwiseMult(prod, fmm_data.eta_val,fmm_data.phi_0_vec);
  CHKERRQ(ierr);

  // Get cheb coeffs from the values and store them in the tree

  {
    size_t n_coeff3=(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3)/6;
    size_t n_nodes3=(cheb_deg+1)*(cheb_deg+1)*(cheb_deg+1);
    PetscInt prod_size;
    ierr = VecGetLocalSize(prod, &prod_size);
    int data_dof=prod_size/(n_nodes3*nlist.size());
    assert(data_dof*n_nodes3*nlist.size()==prod_size);

    PetscScalar *prod_ptr;
    ierr = VecGetArray(prod, &prod_ptr);
#pragma omp parallel for
    for(size_t tid=0;tid<omp_p;tid++){
      size_t i_start=(nlist.size()* tid   )/omp_p;
      size_t i_end  =(nlist.size()*(tid+1))/omp_p;
      pvfmm::Vector<double> coeff_vec(n_coeff3*data_dof);
      pvfmm::Vector<double> val_vec(n_nodes3*data_dof);
      for(size_t i=i_start;i<i_end;i++){

	{ // copy values of the product vector into val_vec which contains the values in the current node
	  size_t prod_offset=i*n_nodes3*data_dof;
	  for(size_t j=0;j<n_nodes3*data_dof;j++) val_vec[j]=PetscRealPart(prod_ptr[j+prod_offset]);
	}


	{ // Compute Chebyshev approx
	  pvfmm::Vector<double>& coeff_vec=nlist[i]->ChebData();
	  if(coeff_vec.Dim()!=(data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6){
	    coeff_vec.ReInit((data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6);
	  }
	  pvfmm::cheb_approx<double,double>(&val_vec[0], cheb_deg, data_dof, &coeff_vec[0]);
	  nlist[i]->DataDOF()=data_dof;
	}
      }
    }
  }

  //run fmm
  tree->ClearFMMData();
  tree->RunFMM();
  tree->Copy_FMMOutput();

  tree2vec(fmm_data,true_sol);
  VecAXPY(true_sol,1,fmm_data.phi_0);
  vec2tree(true_sol,fmm_data);

  return 1;        
}
Exemple #3
0
int mult(Mat M, Vec U, Vec Y){
  PetscErrorCode ierr;
  FMMData* fmm_data=NULL;
  MatShellGetContext(M, &fmm_data);
  FMM_Tree_t* tree=fmm_data->tree;
  const MPI_Comm* comm=tree->Comm();
  int cheb_deg=fmm_data->fmm_mat->ChebDeg();
  std::vector<double>& eta_vec=fmm_data->eta;
  Vec& phi_0_vec=fmm_data->phi_0_vec;
  int omp_p=omp_get_max_threads();
  //int omp_p=1;
  pvfmm::Profile::Tic("FMM_Mul",comm,true);

  std::vector<FMMNode_t*> nlist;
  { // Get non-ghost, leaf nodes.
    std::vector<FMMNode_t*>& nlist_=tree->GetNodeList();
    for(size_t i=0;i<nlist_.size();i++){
      if(nlist_[i]->IsLeaf() && !nlist_[i]->IsGhost()){
	nlist.push_back(nlist_[i]);
      }
    }
  }
  assert(nlist.size()>0);

  // Cheb node points
  size_t n_coeff3=(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3)/6;
  size_t n_nodes3=(cheb_deg+1)*(cheb_deg+1)*(cheb_deg+1);
  std::vector<double> cheb_node_coord1=pvfmm::cheb_nodes<double>(cheb_deg, 1);
#pragma omp parallel for
  for(size_t i=0;i<cheb_node_coord1.size();i++){
    cheb_node_coord1[i]=cheb_node_coord1[i]*2.0-1.0;
  }

  // Input Vector ( \phi_0_vec * U )
  pvfmm::Profile::Tic("FMM_Input",comm,true);
  {
    PetscInt U_size;
    PetscInt phi_0_size;
    ierr = VecGetLocalSize(U, &U_size);
    ierr = VecGetLocalSize(phi_0_vec, &phi_0_size);
    int data_dof=U_size/(n_coeff3*nlist.size());
    assert(data_dof*n_coeff3*nlist.size()==U_size);

    PetscScalar *U_ptr;
    PetscScalar* phi_0_ptr;
    ierr = VecGetArray(U, &U_ptr);
    ierr = VecGetArray(phi_0_vec, &phi_0_ptr);
#pragma omp parallel for
    for(size_t tid=0;tid<omp_p;tid++){
      size_t i_start=(nlist.size()* tid   )/omp_p;
      size_t i_end  =(nlist.size()*(tid+1))/omp_p;
      pvfmm::Vector<double> coeff_vec(n_coeff3*data_dof);
      pvfmm::Vector<double> val_vec(n_nodes3*data_dof);
      pvfmm::Vector<double> phi_0_part(n_nodes3*data_dof);
      for(size_t i=i_start;i<i_end;i++){
	double s=std::pow(2.0,COORD_DIM*nlist[i]->Depth()*0.5*SCAL_EXP);

	{ // coeff_vec: Cheb coeff data for this node
	  size_t U_offset=i*n_coeff3*data_dof;
	  size_t phi_0_offset = i*n_nodes3*data_dof;
	  for(size_t j=0;j<n_coeff3*data_dof;j++){
	    coeff_vec[j]=PetscRealPart(U_ptr[j+U_offset])*s;
	  }
	  for(size_t j=0;j<n_nodes3*data_dof;j++){
	    phi_0_part[j]=PetscRealPart(phi_0_ptr[j+phi_0_offset]);
	  }
	}
	// val_vec: Evaluate coeff_vec at Chebyshev node points
	cheb_eval(coeff_vec, cheb_deg, cheb_node_coord1, cheb_node_coord1, cheb_node_coord1, val_vec);

	{// phi_0_part*val_vec
	  for(size_t j0=0;j0<data_dof;j0++){
	    double* vec=&val_vec[j0*n_nodes3];
	    double* phi_0=&phi_0_part[j0*n_nodes3];
	    for(size_t j1=0;j1<n_nodes3;j1++) vec[j1]*=phi_0[j1];
	  }
	}

	{ // Compute Chebyshev approx
	  pvfmm::Vector<double>& coeff_vec=nlist[i]->ChebData();
	  if(coeff_vec.Dim()!=(data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6){
	    coeff_vec.ReInit((data_dof*(cheb_deg+1)*(cheb_deg+2)*(cheb_deg+3))/6);
	  }
	  pvfmm::cheb_approx<double,double>(&val_vec[0], cheb_deg, data_dof, &coeff_vec[0]);
	  nlist[i]->DataDOF()=data_dof;
	}
      }
    }
  }
  pvfmm::Profile::Toc();

  // Run FMM ( Compute: G[ \eta * u ] )
  tree->ClearFMMData();
  tree->RunFMM();

  // Copy data from tree to Y
  pvfmm::Profile::Tic("tree2vec",comm,true);
  {
    PetscInt Y_size;
    ierr = VecGetLocalSize(Y, &Y_size);
    int data_dof=Y_size/(n_coeff3*nlist.size());

    PetscScalar *Y_ptr;
    ierr = VecGetArray(Y, &Y_ptr);

#pragma omp parallel for
    for(size_t tid=0;tid<omp_p;tid++){
      size_t i_start=(nlist.size()* tid   )/omp_p;
      size_t i_end  =(nlist.size()*(tid+1))/omp_p;
      for(size_t i=i_start;i<i_end;i++){
	pvfmm::Vector<double>& coeff_vec=((FMM_Mat_t::FMMData*) nlist[i]->FMMData())->cheb_out;
	double s=std::pow(0.5,COORD_DIM*nlist[i]->Depth()*0.5*SCAL_EXP);

	size_t Y_offset=i*n_coeff3*data_dof;
	for(size_t j=0;j<n_coeff3*data_dof;j++) Y_ptr[j+Y_offset]=coeff_vec[j]*s;
      }
    }

    ierr = VecRestoreArray(Y, &Y_ptr);
  }
  pvfmm::Profile::Toc();
  // Regularize

  Vec alpha;
  PetscScalar sca = (PetscScalar).00001;
  VecDuplicate(Y,&alpha);
  VecSet(alpha,sca);
  ierr = VecPointwiseMult(alpha,alpha,U);
  ierr = VecAXPY(Y,1,alpha);
  // Output Vector ( Compute:  U + G[ \eta * U ] )
  pvfmm::Profile::Tic("FMM_Output",comm,true);
  ierr = VecAXPY(Y,1,U);CHKERRQ(ierr);
  pvfmm::Profile::Toc();
  ierr = VecDestroy(&alpha); CHKERRQ(ierr);

  pvfmm::Profile::Toc();
  return 0;
}