SparseMatrix Basis::evalBasisJacobian(DenseVector &x) const
{
    // Jacobian basis matrix
    SparseMatrix J(numBasisFunctions(), numVariables);
    //J.setZero(numBasisFunctions(), numInputs);

    // Calculate partial derivatives
    for (unsigned int i = 0; i < numVariables; i++)
    {
        // One column in basis jacobian
        SparseMatrix Ji(1,1);
        Ji.insert(0,0) = 1;
        for (unsigned int j = 0; j < numVariables; j++)
        {
            SparseMatrix temp = Ji;
            SparseMatrix xi;
            if (j == i)
            {
                // Differentiated basis
                xi = bases.at(j).evaluateDerivative(x(j),1);
            }
            else
            {
                // Normal basis
                xi = bases.at(j).evaluate(x(j));
            }
            Ji = kroneckerProduct(temp, xi);
            //myKroneckerProduct(temp,xi,Ji);
            //Ji = kroneckerProduct(Ji, xi).eval();
        }

        // Fill out column
        for (int k = 0; k < Ji.outerSize(); ++k)
        for (SparseMatrix::InnerIterator it(Ji,k); it; ++it)
        {
            if (it.value() != 0)
                J.insert(it.row(),i) = it.value();
        }
        //J.block(0,i,Ji.rows(),1) = bi.block(0,0,Ji.rows(),1);
    }

    J.makeCompressed();

    return J;
}
示例#2
0
	void system::compute_fluid_grad(const bool do_ngb)
	{
#if 0
		const int nimport = Uimport.size(); 
		assert(nimport == (int)site_import.size());
		Wextra_import.resize(nimport);

    const int nactive_site = site_active_list.size();
		const int nactive_site_with_ngb = nactive_site + (do_ngb ? site_with_ngb_active_list.size() : 0);
		
    for (int isite = 0; isite < nactive_site_with_ngb; isite++)
		{
			const int i = isite < nactive_site ? 
				site_active_list[isite] : site_with_ngb_active_list[isite - nactive_site];

			const Cell     &ci     = cell_list[i];
			const Fluid_st &Wst_i  = W_st  [i];
			const Fluid    &Wi     = Wst_i.w;
			const vec3     &ipos   = Wst_i.pos;

			vec3 Ji(0.0);     // current,  J = Del x B

			const vec3 Bi(Wi[Fluid::BX], Wi[Fluid::BY], Wi[Fluid::BZ]);
			
			const int nface = ci.faces().size();	
			for (int iface = 0; iface < nface; iface++)
			{
				const Face &face = face_list[ci.faces()[iface]];

				vec3 dri = face.centroid - ipos;
        if      (dri.x >  0.5*global_domain_size.x) dri.x -= global_domain_size.x;
        else if (dri.x < -0.5*global_domain_size.x) dri.x += global_domain_size.x;
        if      (dri.y >  0.5*global_domain_size.y) dri.y -= global_domain_size.y;
        else if (dri.y < -0.5*global_domain_size.y) dri.y += global_domain_size.y;
        if      (dri.z >  0.5*global_domain_size.z) dri.z -= global_domain_size.z;
        else if (dri.z < -0.5*global_domain_size.z) dri.z += global_domain_size.z;
        assert(std::abs(dri.x) < 0.5*global_domain_size.x);
        assert(std::abs(dri.y) < 0.5*global_domain_size.y);
        assert(std::abs(dri.z) < 0.5*global_domain_size.z);
        
        const vec3 centroid = dri;
				const real area     = face.area();
				const vec3 normal   = face.n * ((centroid * face.n < 0.0) ? (-1.0/area) : (1.0/area));

				const real dsh  = centroid * normal;
				assert(dsh > 0.0);

				const real ids  = (dsh != 0.0) ? 0.5/dsh : 0.0;
				const real idsA = area * ids;

				const vec3 drh = normal * (dsh * idsA);
				const vec3 fij = (centroid - drh) * idsA;
				const int j = site_map(face.ngb<false>(i));
				assert(j >= 0);

				const Fluid &Wj = W_st[j].w;
        const vec3 Bj(Wj[Fluid::BX], Wj[Fluid::BY], Wj[Fluid::BZ]);
        Ji += drh.cross(Bj+Bi) + fij.cross(Bj-Bi);
			}

			const real invV = 1.0/cell_list[i].Volume;
			Ji *= ptcl_import[i].etaOhm * invV;
      
      if (do_ngb) W_st[i].J = Ji;
      else     
      {
        const real dt = t_global - std::abs(W_st[i].tlast);
//        assert(dt > 0.0);
//        W_rec[i].J = (Ji - W_st[i].J) * (1.0/dt);
      }

		}
#endif	
	}