Example #1
0
    void TestNonlinearEquationPde()
    {
        ChastePoint<1> zero1(0);
        ChastePoint<2> zero2(0,0);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        NonlinearEquationPde<1> heat_equation1;
        NonlinearEquationPde<2> heat_equation2;
        NonlinearEquationPde<3> heat_equation3;

        TS_ASSERT_DELTA(heat_equation1.ComputeNonlinearSourceTerm(zero1,u),0.0,1e-12);
        TS_ASSERT_DELTA(heat_equation2.ComputeNonlinearSourceTerm(zero2,u),0.0,1e-12);
        TS_ASSERT_DELTA(heat_equation3.ComputeNonlinearSourceTerm(zero3,u),0.0,1e-12);

        // Diffusion matrices should be equal to identity * u;
        c_matrix<double, 1, 1> diff1 = heat_equation1.ComputeDiffusionTerm(zero1,u);
        c_matrix<double, 2, 2> diff2 = heat_equation2.ComputeDiffusionTerm(zero2,u);
        c_matrix<double, 3, 3> diff3 = heat_equation3.ComputeDiffusionTerm(zero3,u);

        TS_ASSERT_DELTA(diff1(0,0),u,1e-12);

        TS_ASSERT_DELTA(diff2(0,0),u,1e-12);
        TS_ASSERT_DELTA(diff2(1,1),u,1e-12);
        TS_ASSERT_DELTA(diff2(0,1),0,1e-12);

        TS_ASSERT_DELTA(diff3(0,0),u,1e-12);
        TS_ASSERT_DELTA(diff3(1,1),u,1e-12);
        TS_ASSERT_DELTA(diff3(2,2),u,1e-12);
        TS_ASSERT_DELTA(diff3(0,1),0,1e-12);
        TS_ASSERT_DELTA(diff3(0,2),0,1e-12);
        TS_ASSERT_DELTA(diff3(1,2),0,1e-12);
    }
TEST(VectorTest, Normalize)
{
    Point p(3, -4, 0);
    const Point p1(3.0/5, -4.0/5, 0);
    EXPECT_EQ( &p, &( p.normalize() ) ); // It actually returns point itself
    EXPECT_EQ( p1, p );
    
    // Test normalizing when norm is 0
    Point zero1(0, 0, 0);
    const Point zero2(0, 0, 0);
    suppress_warnings();
    zero1.normalize();
    unsuppress_warnings();
    EXPECT_EQ( zero2, zero1 );
}
Example #3
0
    void TestHeatEquation()
    {
        ChastePoint<1> zero1(0);
        ChastePoint<2> zero2(0,0);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        HeatEquation<1> pde1;
        HeatEquation<2> pde2;
        HeatEquation<3> pde3;

        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1,u), 0.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2,u), 0.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3,u), 0.0, 1e-12);

        TS_ASSERT_DELTA(pde1.ComputeDuDtCoefficientFunction(zero1), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeDuDtCoefficientFunction(zero2), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeDuDtCoefficientFunction(zero3), 1.0, 1e-12);

        // Diffusion matrices should be equal to identity
        c_matrix<double, 1, 1> diff1 = pde1.ComputeDiffusionTerm(zero1);
        c_matrix<double, 2, 2> diff2 = pde2.ComputeDiffusionTerm(zero2);
        c_matrix<double, 3, 3> diff3 = pde3.ComputeDiffusionTerm(zero3);

        TS_ASSERT_DELTA(diff1(0,0), 1, 1e-12);

        TS_ASSERT_DELTA(diff2(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(0,1), 0, 1e-12);

        TS_ASSERT_DELTA(diff3(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(2,2), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(0,1), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(0,2), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(1,2), 0, 1e-12);

        Node<1> node(0, zero1);
        TS_ASSERT_DELTA(pde1.ComputeSourceTermAtNode(node,u), 0.0, 1e-12);
    }
Example #4
0
    void TestHeatEquationWithElementDependentSourceTerm()
    {
        // The PDE is set to give elements with index = 0 a source of zero
        // and a source of 1 otherwise.

        std::vector<Node<1>*> one_d_nodes;
        one_d_nodes.push_back(new Node<1>(0, false, 2.0));
        one_d_nodes.push_back(new Node<1>(1, false, 2.5));
        Element<1,1> one_d_element(0u, one_d_nodes);
        ChastePoint<1> zero1(0);

        std::vector<Node<2>*> two_d_nodes;
        two_d_nodes.push_back(new Node<2>(0, false, 0.0, 0.0));
        two_d_nodes.push_back(new Node<2>(1, false, 1.0, 0.0));
        two_d_nodes.push_back(new Node<2>(2, false, 0.0, 1.0));
        Element<2,2> two_d_element(0u, two_d_nodes);
        ChastePoint<2> zero2(0,0);

        std::vector<Node<3>*> three_d_nodes;
        three_d_nodes.push_back(new Node<3>(0, false, 0.0, 0.0, 0.0));
        three_d_nodes.push_back(new Node<3>(1, false, 1.0, 0.0, 0.0));
        three_d_nodes.push_back(new Node<3>(2, false, 0.0, 1.0, 0.0));
        three_d_nodes.push_back(new Node<3>(3, false, 0.0, 0.0, 1.0));
        Element<3,3> three_d_element(0u, three_d_nodes);
        ChastePoint<3> zero3(0,0,0);
        double u = 2.0;

        HeatEquationWithElementDependentSourceTerm<1> pde1;
        HeatEquationWithElementDependentSourceTerm<2> pde2;
        HeatEquationWithElementDependentSourceTerm<3> pde3;

        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1, u, &one_d_element), 0.0, 1e-12);
        one_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde1.ComputeSourceTerm(zero1, u, &one_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2, u, &two_d_element), 0.0, 1e-12);
        two_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde2.ComputeSourceTerm(zero2, u, &two_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3, u, &three_d_element), 0.0, 1e-12);
        three_d_element.ResetIndex(1u);
        TS_ASSERT_DELTA(pde3.ComputeSourceTerm(zero3, u, &three_d_element), 1.0, 1e-12);

        TS_ASSERT_DELTA(pde1.ComputeDuDtCoefficientFunction(zero1), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde2.ComputeDuDtCoefficientFunction(zero2), 1.0, 1e-12);
        TS_ASSERT_DELTA(pde3.ComputeDuDtCoefficientFunction(zero3), 1.0, 1e-12);

        // Diffusion matrices should be equal to identity
        c_matrix<double, 1, 1> diff1 = pde1.ComputeDiffusionTerm(zero1);
        c_matrix<double, 2, 2> diff2 = pde2.ComputeDiffusionTerm(zero2);
        c_matrix<double, 3, 3> diff3 = pde3.ComputeDiffusionTerm(zero3);

        TS_ASSERT_DELTA(diff1(0,0), 1, 1e-12);

        TS_ASSERT_DELTA(diff2(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff2(0,1), 0, 1e-12);

        TS_ASSERT_DELTA(diff3(0,0), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(1,1), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(2,2), 1, 1e-12);
        TS_ASSERT_DELTA(diff3(0,1), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(0,2), 0, 1e-12);
        TS_ASSERT_DELTA(diff3(1,2), 0, 1e-12);

        delete one_d_nodes[0];
        delete one_d_nodes[1];

        delete two_d_nodes[0];
        delete two_d_nodes[1];
        delete two_d_nodes[2];

        delete three_d_nodes[0];
        delete three_d_nodes[1];
        delete three_d_nodes[2];
        delete three_d_nodes[3];
    }
Example #5
0
int main(int argc, char *argv[])
{
	bool cmplx, abc, taper;
	int ix, iz, it, itau, n2, m2;
	int nx, nz, ntau, nt, pad1, nb, nx2, nz2, nzx2, fnx, fnz, fnzx, nk;
	float dt, dtau, par, dz, dx, thresh;
	float tau0, tau;

	float **lt, **rt;
	float *curr, *prev;

	float ***dd, ***mm, **v0;

	sf_axis ax, az, atau;
	sf_file tgather, cgather, left, right;

	int cpuid, numprocs, nth;
	float *sendbuf, *recvbuf;
	MPI_Comm comm=MPI_COMM_WORLD;

	sf_init(argc, argv);

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(comm, &cpuid);
	MPI_Comm_size(comm, &numprocs);

#ifdef _OPENMP
#pragma omp parallel
	{
		nth=omp_get_num_threads();
	}
	sf_warning(">>> Using %d threads <<<", nth);
#endif

	tgather=sf_input("--input");
	cgather=sf_output("--output");
	left=sf_input("left");
	right=sf_input("right");

	az=sf_iaxa(tgather, 1);
	ax=sf_iaxa(tgather, 2);
	atau=sf_iaxa(tgather, 3);

	nz=sf_n(az); dz = sf_d(az); 
	nx=sf_n(ax); dx = sf_d(ax);
	ntau=sf_n(atau); dtau=sf_d(atau); tau0=sf_o(atau);

	if(cpuid==0){
		sf_oaxa(cgather, az, 1);
		sf_oaxa(cgather, ax, 2);
		sf_oaxa(cgather, atau, 3);
	}

	if(!sf_getfloat("dt", &dt)) dt=0.001; /* time interval */
	if(!sf_getint("nb", &nb)) nb=60; /* boundary width */
	if(!sf_getfloat("par", &par)) par=0.01; /* absorbing boundary coefficient */
	if(!sf_getbool("cmplx", &cmplx)) cmplx=false; /* use complex FFT */
	if(!sf_getbool("abc", &abc)) abc=true; /* absorbing boundary condition */
	if(!sf_getint("pad1", &pad1)) pad1=1; /* padding factor on the first axis */
	if(!sf_getbool("taper", &taper)) taper=true; /* tapering */
	if(!sf_getfloat("thresh", &thresh)) thresh=0.92; /* thresholding */

	nx2=nx+2*nb;
	nz2=nz+2*nb;

	nk=fft2_init(cmplx,pad1,nz2,nx2,&fnz,&fnx);

	nzx2=nz2*nx2;
	fnzx=fnz*fnx;

	if (!sf_histint(left,"n1",&n2) || n2 != nzx2) sf_error("Need n1=%d in left",nzx2);
	if (!sf_histint(left,"n2",&m2))  sf_error("Need n2= in left");

	if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2);
	if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk);

	lt = sf_floatalloc2(nzx2,m2);
	rt = sf_floatalloc2(m2,nk);

	sf_floatread(lt[0],nzx2*m2,left);
	sf_floatread(rt[0],m2*nk,right);

	dd=sf_floatalloc3(nz, nx, ntau);
	mm=sf_floatalloc3(nz, nx, ntau);
	v0=sf_floatalloc2(nz2, nx2);
	curr=sf_floatalloc(fnzx);
	prev=sf_floatalloc(fnzx);

	/* broad cast input time-shift gather */
	if(cpuid==0) sf_floatread(dd[0][0], ntau*nx*nz, tgather);
	for(itau=0; itau<ntau; itau++){
		MPI_Bcast(dd[itau][0], nx*nz, MPI_FLOAT, 0, comm);
	}

	/* initialize corrected time-shift gather */
#ifdef _OPENMP
#pragma omp parallel for private(itau, ix, iz)
#endif
	for(itau=0; itau<ntau; itau++)
		for(ix=0; ix<nx; ix++)
			for(iz=0; iz<nz; iz++)
				mm[itau][ix][iz]=0.;

	/* initialize functions */
	lrinit(nx2, nz2, m2, cmplx, pad1, nb, par, abc, lt, rt, taper, thresh, dz, dx);

	/* tau loop */
	for(itau=cpuid; itau<ntau; itau+=numprocs){
		sf_warning("itau=%d/%d", itau+1, ntau);

		tau=tau0+itau*dtau;

		// tau=0
		if(itau==(ntau-1)/2){
			for(ix=0; ix<nx; ix++)
				for(iz=0; iz<nz; iz++)
					mm[itau][ix][iz]=dd[itau][ix][iz];
			continue;
		}

		// calculate v0 (derivative with respect to tau)
		zero2(v0, nz2, nx2);
		if(itau==0){
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					v0[ix+nb][iz+nb]=(dd[1][ix][iz]-dd[0][ix][iz])/dtau;
				}
			}
		} else if (itau==ntau-1){
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					v0[ix+nb][iz+nb]=(dd[ntau-1][ix][iz]-dd[ntau-2][ix][iz])/dtau;
				}
			}
		} else {
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					v0[ix+nb][iz+nb]=(dd[itau+1][ix][iz]-dd[itau-1][ix][iz])/dtau/2.0;
				}
			}
		}

		// calculate u1
		zero1(curr, fnzx);
		zero1(prev, fnzx);
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
		for(ix=0; ix<nx; ix++)
			for(iz=0; iz<nz; iz++)
				curr[(ix+nb)*fnz+iz+nb]=dd[itau][ix][iz];

		// tau>0
		if(itau>(ntau-1)/2){
			// calculate u(t-lt)
			for (ix=0; ix<nx2; ix++)
				for (iz=0; iz<nz2; iz++)
					prev[ix*fnz+iz]=2.*v0[ix][iz]*dt;

			lrupdate(curr,prev);

			for (ix=0; ix<fnzx; ix++)
				curr[ix]=curr[ix]/2.;
			// it loop
			nt=tau/dt+0.5;
			for(it=1; it<nt; it++){
			//	sf_warning("it=%d/%d;", it+1, nt);

				lrupdate(curr,prev);
			} //end of it
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					mm[itau][ix][iz]=curr[(ix+nb)*fnz+iz+nb];
				}
			}
		} // end of positive tau

		// tau<0
		if(itau<(ntau-1)/2){
			//calculate u(t+lt)
			for (ix=0; ix<nx2; ix++)
				for(iz=0; iz<nz2; iz++)
					prev[ix*fnz+iz]=-2.*v0[ix][iz]*dt;

			lrupdate(curr, prev);

			for (ix=0; ix<fnzx; ix++)
				curr[ix]=curr[ix]/2.;

			// it loop
			nt=-tau/dt+0.5;
			for(it=1; it<nt; it++){
				//sf_warning("it=%d/%d;", it+1, nt);

				lrupdate(curr, prev);
			}//end of it
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
			for(ix=0; ix<nx; ix++){
				for(iz=0; iz<nz; iz++){
					mm[itau][ix][iz]=curr[(ix+nb)*fnz+iz+nb];
				}
			}
		}// end of negative tau
	} //end of itau
	MPI_Barrier(comm);

	/* corrected time-shift gather reduction */
	for(itau=0; itau<ntau; itau++){
		if(cpuid==0){
			sendbuf=MPI_IN_PLACE;
			recvbuf=mm[itau][0];
		}else{
			sendbuf=mm[itau][0];
			recvbuf=NULL;
		}
		MPI_Reduce(sendbuf, recvbuf, nz*nx, MPI_FLOAT, MPI_SUM, 0, comm);
	}
	
	if(cpuid==0) sf_floatwrite(mm[0][0], ntau*nz*nx, cgather);

	lrclose();
	MPI_Finalize();
}