int main(int argc, char ** argv) { if( argc < 3 ) { std::cout << "Usage: " << argv[0] << " mesh mesh_out" << std::endl; return 0; } Mesh * m = new Mesh; m->SetFileOption("VERBOSITY","2"); try{m->Load(argv[1]);} catch(...) { std::cout << "Cannot load the mesh " << argv[1] << std::endl; return -1;} Mesh::GeomParam t; t[MEASURE] = CELL | FACE; t[ORIENTATION] = FACE; t[NORMAL] = FACE; //t[BARYCENTER] = CELL; t[CENTROID] = CELL | FACE; m->AssignGlobalID(CELL|FACE); m->PrepareGeometricData(t); double max[3] = {-1.0e20, -1.0e20, -1.0e20}, min[3] = {1.0e20,1.0e20,1.0e20}; Storage::real c[3] = {0,0,0}, nrm[3] = {0,0,0}; for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it) { it->Centroid(c); if( c[0] > max[0] ) max[0] = c[0]; if( c[1] > max[1] ) max[1] = c[1]; if( c[2] > max[2] ) max[2] = c[2]; if( c[0] < min[0] ) min[0] = c[0]; if( c[1] < min[1] ) min[1] = c[1]; if( c[2] < min[2] ) min[2] = c[2]; } if( max[0] <= min[0] ) {std::cout << "strange X " << min[0] << ":" << max[0] << std::endl; return -1;} if( max[1] <= min[1] ) {std::cout << "strange Y " << min[1] << ":" << max[1] << std::endl; return -1;} if( max[2] <= min[2] ) { //2d mesh if( m->GetDimensions() == 3 ) { //offset from z-plane min[2] -= 0.0001; max[2] += 0.0001; } else { min[2] = -0.0001; max[2] = +0.0001; } } std::cout << "Mesh bounds: " << min[0] << ":" << max[0] << " " << min[1] << ":" << max[1] << " " << min[2] << ":" << max[2] << std::endl; Tag material; if( m->HaveTag("PERM") ) m->DeleteTag(m->GetTag("PERM")); Tag vel = m->CreateTag("REFERENCE_VELOCITY",DATA_REAL,CELL,NONE,3); Tag force = m->CreateTag("FORCE",DATA_REAL,CELL,NONE,1); Tag tensor = m->CreateTag("PERM",DATA_REAL,CELL,NONE,6); Tag solution_val = m->CreateTag("REFERENCE_SOLUTION",DATA_REAL,CELL|FACE|EDGE|NODE,NONE,1); Tag solution_flux = m->CreateTag("REFERENCE_FLUX",DATA_REAL,FACE,FACE,1); Tag saddle_val = m->CreateTag("SADDLE_SOLUTION",DATA_REAL,CELL,NONE,4); Tag saddle_flux = m->CreateTag("SADDLE_FLUX",DATA_REAL,FACE,NONE,4); Tag bndcond = m->CreateTag("BOUNDARY_CONDITION",DATA_REAL,FACE|EDGE,FACE|EDGE,3); { Storage::bulk_array name = m->self()->BulkArray(m->CreateTag("PROBLEMNAME",DATA_BULK,MESH,NONE)); name.replace(name.begin(),name.end(),problem_name.begin(),problem_name.end()); } for(Mesh::iteratorElement it = m->BeginElement(CELL|FACE|EDGE|NODE); it != m->EndElement(); ++it) { it->Centroid(c); if( it->GetElementType() == CELL ) { Storage::real_array perm = it->RealArray(tensor); perm[0] = 1.5; perm[1] = 0.5; perm[2] = 0.0; perm[3] = 1.5; perm[4] = 0.0; perm[5] = 1.0; } Storage::real x = c[0];//(c[0]-min[0])/(max[0]-min[0]); Storage::real y = c[1];//(c[1]-min[1])/(max[1]-min[1]); Storage::real z = c[2];//(c[2]-min[2])/(max[2]-min[2]); Storage::real sol = 16.0*(1-x)*y*(1-y); Storage::real flux; Storage::real dsolx = 16*(y-1)*y; Storage::real dsoly = 16*(x-1)*(2*y-1); if( it->GetElementType() == CELL ) it->Real(force) = -16*(2*y+3*x-4); it->Real(solution_val) = sol; if( it->GetElementType() == CELL ) { it->RealArray(vel)[0] = 1.5*dsolx + 0.5*dsoly; it->RealArray(vel)[1] = 0.5*dsolx + 1.5*dsoly; it->RealArray(vel)[2] = 0; it->RealArray(saddle_val)[0] = 1.5*dsolx + 0.5*dsoly; it->RealArray(saddle_val)[1] = 0.5*dsolx + 1.5*dsoly; it->RealArray(saddle_val)[2] = 0; it->RealArray(saddle_val)[3] = sol; } if( it->GetElementType() == FACE ) { it->getAsFace()->UnitNormal(nrm); flux = (1.5*nrm[0]+0.5*nrm[1])*dsolx + (0.5*nrm[0]+1.5*nrm[1])*dsoly; if( !(z < eps || z > 1.0-eps ) ) { it->Real(solution_flux) = -flux; if( it->getAsFace()->Boundary() ) { Storage::real_array bc = it->RealArray(bndcond); bc[0] = 1.0; bc[1] = 0.0; bc[2] = sol; } } it->RealArray(saddle_flux)[0] = sol*(1.5*nrm[0]+0.5*nrm[1]); it->RealArray(saddle_flux)[1] = sol*(0.5*nrm[0]+1.5*nrm[1]); it->RealArray(saddle_flux)[2] = sol*nrm[2]; it->RealArray(saddle_flux)[3] = flux; } if( it->GetElementType() == EDGE ) { if( it->Boundary() ) { Storage::real_array bc = it->RealArray(bndcond); bc[0] = 1.0; bc[1] = 0.0; bc[2] = sol; } } } std::cout << "Saving output to " << argv[2] << std::endl; m->Save(argv[2]); delete m; }
int main(int argc, char *argv[]) { if (argc < 2) { std::cout << "Usage: " << argv[0] << " nx|grid_name [alpha=0.4] [outer_boundary_pressure=0.0] [inner_boundary_pressure=1.0] [cut_grid=1] [is2d=1]" << std::endl; return -1; } Mesh * mesh; double alpha=0.2; double h; double outer_boundary_pressure = 0.0; double inner_boundary_pressure = 1.0; int cut_grid = 1; int is2d = 0; int n = 20 + 1; mesh = new Mesh(); if (argc > 1) { if( atoi(argv[1]) ) { n = atoi(argv[1])+1; h = 1.0 / (n-1); std::cout << "Mesh: cube " << n << std::endl; } else { mesh->Load(argv[1]); std::cout << "Mesh: " << argv[1] << std::endl; n = 0; } } std::cout << "Mesh radius: " << h << std::endl; if( argc > 2 ) alpha = atof(argv[2]); std::cout << "Alpha: " << alpha << std::endl; if( argc > 3 ) outer_boundary_pressure = atof(argv[3]); if( argc > 4 ) inner_boundary_pressure = atof(argv[4]); std::cout << "Boundaries: " << outer_boundary_pressure << " " << inner_boundary_pressure << std::endl; if( argc > 5 ) cut_grid = atoi(argv[5]); if( cut_grid ) std::cout << "Cutting center of the grid." << std::endl; if( argc > 6 ) is2d = atoi(argv[6]); if( is2d ) std::cout << "Using 2d setup" << std::endl; else std::cout << "Using 3d setup" << std::endl; double ratio = 1000; if( argc > 7 ) ratio = atof(argv[7]); std::cout << "Anisotropy ratio: " << ratio << std::endl; srand(0);//(unsigned)time(NULL)); if( n ) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { Storage::real xyz[3]; bool mark = false; xyz[0] = i * 1.0 / (n - 1); xyz[1] = j * 1.0 / (n - 1); xyz[2] = k * 1.0 / (n - 1); Node c = mesh->CreateNode(xyz); if (c->LocalID() != V_ID(i, j, k)) printf("v_id = %d, [i,j,k] = %d\n", c->LocalID(), V_ID(i, j, k)); } } } const INMOST_DATA_INTEGER_TYPE nvf[24] = { 2, 3, 1, 0, 4, 5, 7, 6, 0, 1, 5, 4, 3, 2, 6, 7, 2, 0, 4, 6, 1, 3, 7, 5 }; const INMOST_DATA_INTEGER_TYPE numnodes[6] = { 4, 4, 4, 4, 4, 4 }; for (int i = 1; i < n; i++) { for (int j = 1; j < n; j++) { for (int k = 1; k < n; k++) { ElementArray<Node> verts(mesh,8); verts[0] = mesh->NodeByLocalID(V_ID(i - 1, j - 1, k - 1)); verts[1] = mesh->NodeByLocalID(V_ID(i - 0, j - 1, k - 1)); verts[2] = mesh->NodeByLocalID(V_ID(i - 1, j - 0, k - 1)); verts[3] = mesh->NodeByLocalID(V_ID(i - 0, j - 0, k - 1)); verts[4] = mesh->NodeByLocalID(V_ID(i - 1, j - 1, k - 0)); verts[5] = mesh->NodeByLocalID(V_ID(i - 0, j - 1, k - 0)); verts[6] = mesh->NodeByLocalID(V_ID(i - 1, j - 0, k - 0)); verts[7] = mesh->NodeByLocalID(V_ID(i - 0, j - 0, k - 0)); mesh->CreateCell(verts,nvf,numnodes,6); } } } } if( cut_grid ) { for (Mesh::iteratorCell it = mesh->BeginCell(); it != mesh->EndCell(); ++it) { Storage::real cnt[3]; it->Centroid(cnt); if( cnt[0] > 0.25 && cnt[0] < 0.75 && cnt[1] > 0.25 && cnt[1] < 0.75 ) it->Delete(); } for (Mesh::iteratorElement it = mesh->BeginElement(FACE|EDGE|NODE); it != mesh->EndElement(); ++it) if( it->nbAdjElements(CELL) == 0 ) it->Delete(); } if( alpha > 0.0 ) //skewness { const double eps = 1.0e-6; for( Mesh::iteratorNode it = mesh->BeginNode(); it != mesh->EndNode(); ++it) { Storage::real_array coords = it->Coords(); Storage::real h = 1.0e20; ElementArray<Cell> it_cells = it->getCells(); for(int k = 0; k < it_cells.size(); ++k) { Storage::real maxmin[6]; maxmin[0] = -1e20; maxmin[1] = 1e20; maxmin[2] = -1e20; maxmin[3] = 1e20; ElementArray<Node> nodes = it_cells[k].getNodes(); for (ElementArray<Node>::iterator it = nodes.begin(); it != nodes.end(); it++) { Storage::real_array cc = it->Coords(); for (int i = 0; i < (int)cc.size(); i++) { if (maxmin[2 * i + 0] < cc[i]) maxmin[2 * i + 0] = cc[i]; //max if (maxmin[2 * i + 1] > cc[i]) maxmin[2 * i + 1] = cc[i]; //min } } h = std::min(h,sqrt((maxmin[2]-maxmin[3])*(maxmin[2]-maxmin[3])+(maxmin[0]-maxmin[1])*(maxmin[0]-maxmin[1]))); } if( coords[0] > eps && coords[0] < 1.0-eps && coords[1] > eps && coords[1] < 1.0-eps ) { if( !(coords[0] > 4.0/9.0-eps && coords[0] < 5.0/9.0+eps && coords[1] > 4.0/9.0-eps && coords[1] < 5.0/9.0+eps) ) { coords[0] += alpha*h*(2.0*rand()/RAND_MAX-1.0); coords[1] += alpha*h*(2.0*rand()/RAND_MAX-1.0); } } } } for( Mesh::iteratorNode it = mesh->BeginNode(); it != mesh->EndNode(); ++it) { Storage::real_array coords = it->Coords(); coords[0] = 2*coords[0]-1; coords[1] = 2*coords[1]-1; } mesh->ReorderEmpty(CELL|FACE|EDGE|NODE); { // Prepare geometrical data on the mesh. Mesh::GeomParam table; table[CENTROID] = CELL | FACE; //Compute averaged center of mass table[NORMAL] = FACE; //Compute normals table[ORIENTATION] = FACE; //Check and fix normal orientation table[MEASURE] = CELL | FACE; //Compute volumes and areas //table[BARYCENTER] = CELL | FACE; //Compute volumetric center of mass mesh->RemoveGeometricData(table); mesh->PrepareGeometricData(table); //Ask to precompute the data } printf("nodes: %d edges: %d faces: %d cells: %d\n", mesh->NumberOfNodes(), mesh->NumberOfEdges(), mesh->NumberOfFaces(), mesh->NumberOfCells()); { Storage::bulk_array name = mesh->self()->BulkArray(mesh->CreateTag("PROBLEMNAME",DATA_BULK,MESH,NONE)); name.replace(name.begin(),name.end(),problem_name.begin(),problem_name.end()); } Tag bndcond = mesh->CreateTag("BOUNDARY_CONDITION",DATA_REAL,FACE,FACE,3); Tag velocity = mesh->CreateTag("VELOCITY",DATA_REAL,FACE,NONE,1); Tag reaction = mesh->CreateTag("REACTION",DATA_REAL,CELL,NONE,1); Tag tensor = mesh->CreateTag("PERM", DATA_REAL, CELL, NONE, 1); Tag force = mesh->CreateTag("FORCE",DATA_REAL,CELL,NONE,1); Tag vel3 = mesh->CreateTag("VELVEC",DATA_REAL,CELL,NONE,3); Tag refsol = mesh->CreateTag("REFERENCE_SOLUTION",DATA_REAL,CELL,NONE,1); Tag refflux = mesh->CreateTag("REFERENCE_FLUX",DATA_REAL,FACE,NONE,1); Tag zone = mesh->CreateTag("ZONE",DATA_INTEGER,CELL,NONE,1); int numinner = 0, numouter = 0; int numinnern = 0, numoutern = 0; const double eps = 1.0e-6; const double mu = 1.0e-3; const double velmult = 1; for(Mesh::iteratorFace it = mesh->BeginFace(); it != mesh->EndFace(); ++it) { Storage::real cnt[3], nrm[3]; it->Centroid(cnt); it->UnitNormal(nrm); Storage::real x = cnt[0]; Storage::real y = cnt[1]; Storage::real z = cnt[2]; Storage::real r = sqrt(x*x+y*y); Storage::real theta = atan2(y,x);//+pi; Storage::real sol, diff, flux, velnrm, dsolx, dsoly; Storage::real vel[3] = {-y/(r*r)*velmult,x/(r*r)*velmult,0.0}; if( theta < 0 ) theta = 2*pi + theta; velnrm = nrm[0]*vel[0] + nrm[1]*vel[1] + nrm[2]*vel[2]; if( theta < pi ) { diff = pi; sol = (theta-pi)*(theta-pi); dsolx = -2*y*(theta-pi)/(r*r); dsoly = 2*x*(theta-pi)/(r*r); flux = velnrm*sol - diff*(dsolx*nrm[0] + dsoly*nrm[1]); } else { diff = 0; sol = 3*pi*(theta-pi); flux = velnrm*sol; } it->Real(refflux) = flux; it->Real(velocity) = velnrm; if( it->Boundary() && z > 0+eps && z < 1-eps) { Storage::real_array bc = it->RealArray(bndcond); bc[0] = 1; bc[1] = 0; bc[2] = sol; } } std::cout << "Outer faces " << numouter << " inner faces " << numinner << std::endl; std::cout << "Outer nodes " << numoutern << " inner nodes " << numinnern << std::endl; for (Mesh::iteratorCell it = mesh->BeginCell(); it != mesh->EndCell(); ++it) { Storage::real cnt[3]; it->Centroid(cnt); Storage::real f = 0; Storage::real x = cnt[0]; Storage::real y = cnt[1]; Storage::real r = sqrt(x*x+y*y); Storage::real theta = atan2(y,x);//+pi; Storage::real sol, diff; Storage::real vel[3] = {-y/(r*r)*velmult,x/(r*r)*velmult,0.0}; if( theta < 0 ) theta = 2*pi + theta; it->Centroid(cnt); if( theta < pi ) { diff = pi; //diff = 0; sol = (theta-pi)*(theta-pi); f = mu*sol + 2*(theta-pi)/(r*r)*velmult - diff*2/(r*r); it->Integer(zone) = 0; } else { diff = 0; sol = 3*pi*(theta-pi); f = mu*sol + 3*pi/(r*r)*velmult; it->Integer(zone) = 1; } it->Real(force) = f; it->Real(reaction) = mu; it->Real(refsol) = sol; it->Real(tensor) = diff; Storage::real_array svel = it->RealArray(vel3); svel[0] = vel[0]; svel[1] = vel[1]; svel[2] = vel[2]; } printf("I'm ready!\n"); //mesh->Save("grid.vtk"); mesh->Save("grid_out.pmf"); //mesh->Save("grid.gmv"); printf("File written!\n"); delete mesh; return 0; }
int main(int argc, char ** argv) { if( argc < 3 ) { std::cout << "Usage: " << argv[0] << " mesh mesh_out [sigma:0.2 incline:1 y_low:0.25 y_high:0.5]" << std::endl; return 0; } Mesh * m = new Mesh; m->SetFileOption("VERBOSITY","2"); try{m->Load(argv[1]);} catch(...) { std::cout << "Cannot load the mesh " << argv[1] << std::endl; return -1;} Storage::real sigma = 0.2, y_low = 0.25, y_high = 0.5, alpha = 0.15; if( argc > 3 ) sigma = atof(argv[3]); //for(Mesh::iteratorTag t = m->BeginTag(); t != m->EndTag(); ++t) // if( t->GetTagName().substr(0,9) == "GEOM_UTIL" ) m->DeleteTag(*t); if( argc <= 4 || (argc > 4 && atoi(argv[4])) ) { double max[3] = {-1.0e20, -1.0e20, -1.0e20}, min[3] = {1.0e20,1.0e20,1.0e20}; for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it) { Storage::real_array c = it->Coords(); if( c[0] > max[0] ) max[0] = c[0]; if( c[1] > max[1] ) max[1] = c[1]; if( c[2] > max[2] ) max[2] = c[2]; if( c[0] < min[0] ) min[0] = c[0]; if( c[1] < min[1] ) min[1] = c[1]; if( c[2] < min[2] ) min[2] = c[2]; } std::cout << "You asked to incline the grid to honour discontinuities" << std::endl; std::cout << "and I assume that the initial grid is rectangular." << std::endl; for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it) { Storage::real_array c = it->Coords(); Storage::real x = c[0]; Storage::real y = c[1]; Storage::real d = 0.0; Storage::real y1 = sigma*(x-0.5)+0.475; Storage::real y2 = sigma*(x-0.5)+0.475+0.05; if( y <= y_low ) d = y/y_low*(y1-y_low); else if( y >= y_low && y <= y_high ) d = (y1-y_low) + (y-y_low)/(y_high-y_low)*((y2-y_high)-(y1-y_low)); else d = (1-(y-y_high)/(1-y_high))*(y2-y_high); c[1] += d; } //introduce skewness /* for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it) { Storage::real_array c = it->Coords(); Storage::real x = c[0]; Storage::real y = c[1]; Storage::real y1 = sigma*(x-0.5)+0.475; Storage::real y2 = sigma*(x-0.5)+0.475+0.05; Storage::real rndx = (rand()*1.0/RAND_MAX*2-1); Storage::real rndy = (rand()*1.0/RAND_MAX*2-1); Storage::real h = 1.0e20; ElementArray<Cell> it_cells = it->getCells(); for(int k = 0; k < it_cells.size(); ++k) { Storage::real maxmin[6]; maxmin[0] = -1e20; maxmin[1] = 1e20; maxmin[2] = -1e20; maxmin[3] = 1e20; ElementArray<Node> nodes = it_cells[k].getNodes(); for (ElementArray<Node>::iterator it = nodes.begin(); it != nodes.end(); it++) { Storage::real_array cc = it->Coords(); for (int i = 0; i < (int)cc.size(); i++) { if (maxmin[2 * i + 0] < cc[i]) maxmin[2 * i + 0] = cc[i]; //max if (maxmin[2 * i + 1] > cc[i]) maxmin[2 * i + 1] = cc[i]; //min } } h = std::min(h,sqrt((maxmin[2]-maxmin[3])*(maxmin[2]-maxmin[3])+(maxmin[0]-maxmin[1])*(maxmin[0]-maxmin[1]))); } if( fabs(y-y1) > 1.0e-9 && fabs(y-y2) > 1.0e-9 && x > 0 && x < 1 && y > 0 && y < 1 ) { c[0] += rndx*h*alpha; c[1] += rndy*h*alpha; } } */ } Mesh::GeomParam t; t[MEASURE] = CELL | FACE; t[ORIENTATION] = FACE; t[NORMAL] = FACE; //t[BARYCENTER] = CELL; t[CENTROID] = CELL | FACE | EDGE | NODE; m->AssignGlobalID(CELL|FACE); //m->RemoveGeometricData(t); m->PrepareGeometricData(t); double max[3] = {-1.0e20, -1.0e20, -1.0e20}, min[3] = {1.0e20,1.0e20,1.0e20}; Storage::real c[3] = {0,0,0}, nrm[3] = {0,0,0}; for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it) { it->Centroid(c); if( c[0] > max[0] ) max[0] = c[0]; if( c[1] > max[1] ) max[1] = c[1]; if( c[2] > max[2] ) max[2] = c[2]; if( c[0] < min[0] ) min[0] = c[0]; if( c[1] < min[1] ) min[1] = c[1]; if( c[2] < min[2] ) min[2] = c[2]; } if( max[0] <= min[0] ) {std::cout << "strange X " << min[0] << ":" << max[0] << std::endl; return -1;} if( max[1] <= min[1] ) {std::cout << "strange Y " << min[1] << ":" << max[1] << std::endl; return -1;} if( max[2] <= min[2] ) { //2d mesh if( m->GetDimensions() == 3 ) { //offset from z-plane min[2] -= 0.0001; max[2] += 0.0001; } else { min[2] = -0.0001; max[2] = +0.0001; } } std::cout << "Mesh bounds: " << min[0] << ":" << max[0] << " " << min[1] << ":" << max[1] << " " << min[2] << ":" << max[2] << std::endl; if( m->HaveTag("PERM") ) m->DeleteTag(m->GetTag("PERM")); if( m->HaveTag("MATERIAL") ) m->DeleteTag(m->GetTag("MATERIAL")); Tag rvel = m->CreateTag("REFERENCE_VELOCITY",DATA_REAL,CELL,NONE,3); Tag material = m->CreateTag("MATERIAL",DATA_INTEGER,CELL|EDGE|FACE|NODE,NONE,1); Tag tensor = m->CreateTag("PERM",DATA_REAL,CELL,NONE,3); Tag solution_val = m->CreateTag("REFERENCE_SOLUTION",DATA_REAL,CELL|FACE|EDGE|NODE,NONE,1); Tag saddle_val = m->CreateTag("SADDLE_SOLUTION",DATA_REAL,CELL,NONE,4); Tag solution_flux = m->CreateTag("REFERENCE_FLUX",DATA_REAL,FACE,FACE,1); Tag saddle_flux = m->CreateTag("SADDLE_FLUX",DATA_REAL,FACE,NONE,4); Tag bndcond = m->CreateTag("BOUNDARY_CONDITION",DATA_REAL,FACE|EDGE|NODE,FACE|EDGE|NODE,3); Tag velocity, force; { Storage::bulk_array name = m->self()->BulkArray(m->CreateTag("PROBLEMNAME",DATA_BULK,MESH,NONE)); name.replace(name.begin(),name.end(),problem_name.begin(),problem_name.end()); } double velmult = 0.0; if( velmult ) { force = m->CreateTag("FORCE",DATA_REAL,CELL,NONE,1); velocity = m->CreateTag("VELOCITY",DATA_REAL,FACE,NONE,1); } for(Mesh::iteratorElement it = m->BeginElement(CELL|FACE|EDGE|NODE); it != m->EndElement(); ++it) { it->Centroid(c); Storage::real x = c[0];//(c[0]-min[0])/(max[0]-min[0]); Storage::real y = c[1];//(c[1]-min[1])/(max[1]-min[1]); Storage::real z = c[2];//(c[2]-min[2])/(max[2]-min[2]); Storage::real r = 1;//sqrt((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)); //Storage::real vel[3] = {-(y-0.5)/(r*r)*velmult,(x-0.5)/(r*r)*velmult,0.0}; Storage::real vel[3] = {-0.5*velmult,velmult,0.0}; int zone = 0; double phi1 = y - sigma*(x-0.5) - 0.475; double phi2 = phi1 - 0.05; double alpha; if( phi1 < 0 ) zone = 1; else if( phi1 >= 0 && phi2 < 0 ) zone = 2; else zone = 3; //else printf("%s:%d oops!\n",__FILE__,__LINE__); it->IntegerDF(material) = zone; Storage::real sol, dsolx, dsoly; Storage::real flux; if( zone == 2 ) { alpha = 0.01; } else { alpha = 1; } sol = 0; if( zone == 1 ) { sol = -phi1; dsolx = sigma; dsoly = -1; } else if( zone == 2 ) { sol = -phi1/0.01; dsolx = sigma/0.01; dsoly = -1/0.01; } else if( zone == 3 ) { sol = -phi2 - 0.05/0.01; dsolx = sigma; dsoly = -1; } sol += 6; //pick solution up for positivity Storage::real K[6] = { alpha, 0.0, 0.0, alpha, 0, 1 }; if( it->GetElementType() == CELL ) { Storage::real_array perm = it->RealArray(tensor); perm[0] = alpha; perm[1] = alpha; perm[2] = 1; } it->Real(solution_val) = sol; if( it->GetElementType() == CELL && velmult ) { it->Real(force) = (dsolx*vel[0] + dsoly*vel[1]); } if( it->GetElementType() == CELL ) { it->RealArray(rvel)[0] = dsolx*alpha; it->RealArray(rvel)[1] = dsoly*alpha; it->RealArray(rvel)[2] = 0; it->RealArray(saddle_val)[0] = dsolx*alpha; it->RealArray(saddle_val)[1] = dsoly*alpha; it->RealArray(saddle_val)[2] = 0; it->RealArray(saddle_val)[3] = sol; } if( it->GetElementType() == FACE ) { it->getAsFace()->UnitNormal(nrm); double adv_flux = 0; if( velmult ) { double nvel = vel[0]*nrm[0] + vel[1]*nrm[1] + vel[2]*nrm[2]; it->Real(velocity) = nvel; adv_flux = sol*nvel; } flux = -((K[0]*nrm[0]+K[1]*nrm[1])*dsolx + (K[1]*nrm[0]+K[3]*nrm[1])*dsoly) + adv_flux; it->RealArray(saddle_flux)[0] = sol*(K[0]*nrm[0]+K[1]*nrm[1]); it->RealArray(saddle_flux)[1] = sol*(K[1]*nrm[0]+K[3]*nrm[1]); it->RealArray(saddle_flux)[2] = sol*nrm[2]; it->RealArray(saddle_flux)[3] = -flux; if( !(z < eps || z > 1.0-eps ) ) { it->Real(solution_flux) = flux; if( it->getAsFace()->Boundary() ) { Storage::real_array bc = it->RealArray(bndcond); bc[0] = 1.0; bc[1] = 0.0; bc[2] = sol; } } } if( it->GetElementType() & (EDGE | NODE) ) { if( (x < eps || x > 1.0-eps || y < eps || y > 1.0-eps) ) { if( it->Boundary() ) { Storage::real_array bc = it->RealArray(bndcond); bc[0] = 1.0; bc[1] = 0.0; bc[2] = sol; } } } } std::cout << "Saving output to " << argv[2] << std::endl; m->Save(argv[2]); delete m; }