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); }
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; }