void StVKReducedInternalForces::InitGravity(VolumetricMesh * volumetricMesh_, double * U_)
{
  VolumetricMesh * mesh = volumetricMesh;
  if (volumetricMesh_ != NULL)
    mesh = volumetricMesh_;
  
  double * UB = NULL;
  if (U != NULL)
    UB = U;
  if (U_ != NULL)
    UB = U_;

  if ((mesh == NULL) || (UB ==NULL))
  {
    printf("Error: cannot init gravity. Mesh or basis is not specified.\n");
    return;
  }

  if (reducedGravityForce == NULL)
  {
    int n = mesh->getNumVertices();
    double * gravityForce = (double*) malloc (sizeof(double) * 3 * n);
    unitReducedGravityForce = (double*) malloc (sizeof(double) * r);
    reducedGravityForce = (double*) malloc (sizeof(double) * r);
    mesh->computeGravity(gravityForce, 1.0);
    ProjectVector(3*n, r, UB, unitReducedGravityForce, gravityForce);
    //for(int i=0; i<r; i++)
      //printf("%G\n", unitReducedGravityForce[i]);
    free(gravityForce);
  }

  for(int i=0; i<r; i++)
    reducedGravityForce[i] = g * unitReducedGravityForce[i];

  //printf("Altered gravity to %G\n", g);
}
예제 #2
0
int main(int argc, char* argv[])
{
	char* inputFileName = "I:/Programs/VegaFEM-v2.1/models/turtle/turtle-volumetric-homogeneous.veg";
	VolumetricMesh* volumetricMesh = VolumetricMeshLoader::load(inputFileName);
	if (volumetricMesh == NULL)
	{
		PRINT_F("load failed!");
	}
	else 
	{
		PRINT_F("%d vertices, %d elements", volumetricMesh->getNumVertices(), volumetricMesh->getNumElements());
	}

	TetMesh* tetMesh;
	if (volumetricMesh->getElementType() == VolumetricMesh::TET)
	{
		tetMesh = (TetMesh*) volumetricMesh;
	}
	else 
		PRINT_F("not a tet mesh\n");

	CorotationalLinearFEM* deformableModel = new CorotationalLinearFEM(tetMesh);
	ForceModel* forceModel = new CorotationalLinearFEMForceModel(deformableModel);

	int nVtx = tetMesh->getNumVertices();
	int r = 3 * nVtx;
	double timestep = 0.0333;

	SparseMatrix* massMatrix;
	GenerateMassMatrix::computeMassMatrix(tetMesh, &massMatrix, true);
	massMatrix->SaveToMatlabFormat("massMatrix.m");

	PRINT_F("%d rows, %d cols\n", massMatrix->GetNumRows(), massMatrix->GetNumColumns());
	int positiveDefiniteSolver = 0;

	int numConstrainedDOFs = 9;
	int constrainedDOFs[9]= {12,13,14,30,31,32,42,43,44};

	double dampingMassCoef = 0.0;
	double dampingStiffnessCoef = 0.01;


	ImplicitBackwardEulerSparse* integrator = new ImplicitBackwardEulerSparse(r, timestep, massMatrix, forceModel, positiveDefiniteSolver, numConstrainedDOFs, constrainedDOFs, dampingMassCoef, dampingStiffnessCoef);

	//CentralDifferencesSparse* integrator = new CentralDifferencesSparse(r, timestep, massMatrix, forceModel, numConstrainedDOFs, constrainedDOFs, dampingMassCoef, dampingStiffnessCoef);

	double * f = new double[r];
	int numTimesteps = 10;
	double*u = new double[r];
	for (int i = 0; i < numTimesteps; ++i)
	{
		integrator->SetExternalForcesToZero();
		if (i==0)
		{
			for (int j = 0; j < r; j++)
				f[j] = 0;
			f[37] = -500;
			integrator->SetExternalForces(f);
		}
		integrator->GetqState(u);
		PRINT_F("v = [", i);
		for (int ithVtx = 0; ithVtx < nVtx; ++ithVtx)
			PRINT_F("%lf, %lf, %lf\n", u[ithVtx*3],u[ithVtx*3+1],u[ithVtx*3+2]);
		PRINT_F("];");

		integrator->DoTimestep();
	}

	return 0;
}
int main(int argc, char ** argv)
{
  if (argc < 4)
  {
    printf("Generates an interpolant between a given volumetric mesh and a surface obj mesh.\n");
    printf("Usage: %s <volumetric mesh file> <target obj file> <output interpolant file> [-s volumetric mesh element list output filename] [-z threshold] [-S] [-T]\n",argv[0]);
    printf("-s : output list of (1-indexed) volumetric mesh elements that contain at least one obj mesh vertex\n");
    printf("-z : assign zero interpolation to vertices too far away from the volumetric mesh\n");
    return 0;
  }

  char * meshFile = argv[1];
  char * objMeshname = argv[2];
  char * outputFilename = argv[3];

  char outputElementFilename[4096] = "__none";
  char zeroThresholdString[4096] = "__none";

  opt_t opttable[] =
  {
    { (char*)"s", OPTSTR, &outputElementFilename },
    { (char*)"z", OPTSTR, &zeroThresholdString },
    { NULL, 0, NULL }
  };

  argv += 3;
  argc -= 3;
  int optup = getopts(argc,argv,opttable);
  if (optup != argc)
  {
    printf("Error parsing options. Error at option %s.\n",argv[optup]);
    return 1;
  }

  double threshold;
  if (strcmp(zeroThresholdString,"__none") == 0)
    threshold = -1;
  else
    threshold = strtod(zeroThresholdString, NULL);

  VolumetricMesh * volumetricMesh = VolumetricMeshLoader::load(meshFile);
  
  if (volumetricMesh == NULL)
  {
    printf("Error: unable to load the volumetric mesh from %s.\n", meshFile);
    exit(1);
  }
 
  int n = volumetricMesh->getNumVertices();
  int nel = volumetricMesh->getNumElements();
  printf("Info on %s:\n", meshFile);
  printf("Num vertices: %d\n", n);
  printf("Num elements: %d\n", nel);

  ObjMesh * objMesh = new ObjMesh(objMeshname);

  int numInterpolationLocations = objMesh->getNumVertices();
  double * interpolationLocations = (double*) malloc (sizeof(double) * 3 * numInterpolationLocations);
  for(int i=0; i< numInterpolationLocations; i++)
  {
    Vec3d pos = objMesh->getPosition(i);
    interpolationLocations[3*i+0] = pos[0];
    interpolationLocations[3*i+1] = pos[1];
    interpolationLocations[3*i+2] = pos[2];
  }

  int * vertices;
  double * weights;

  int * elementList;
  int ** elementListp = NULL;
  if (strcmp(outputElementFilename, "__none") != 0)
  {
    elementListp = &elementList;    
  }

  int verbose = 1;
  int numExternalVertices;
  numExternalVertices = volumetricMesh->generateInterpolationWeights(numInterpolationLocations, interpolationLocations, &vertices, &weights, threshold, elementListp, verbose);

  printf("Saving weights to %s...\n", outputFilename); fflush(NULL);
  volumetricMesh->saveInterpolationWeights(outputFilename, numInterpolationLocations, volumetricMesh->getNumElementVertices(), vertices, weights);

  if (strcmp(outputElementFilename, "__none") != 0)
  {
    set<int> uniqueElementSet;
    for(unsigned int i=0; i<numInterpolationLocations; i++)
      uniqueElementSet.insert(elementList[i]);

    vector<int> uniqueElementList;
    for(set<int>::iterator iter = uniqueElementSet.begin(); iter != uniqueElementSet.end(); iter++)
      uniqueElementList.push_back(*iter);

    LoadList saveList;
    sort(uniqueElementList.begin(), uniqueElementList.end());
    int oneIndexed = 1;
    saveList.save(outputElementFilename, uniqueElementList.size(), &uniqueElementList[0], oneIndexed);
  }
  printf("\n");

  return 0;
}