F. Delete The Edges

博客介绍了如何在一个图中找到欧拉回路,并根据特定模式删除边。通过枚举星图中心,判断奇数点数量,实现边的删除。算法时间复杂度分析为O(m*m),其中m为边的数量。代码实现包括图的构建、DFS遍历和解决方案检查。

 给出一个图,求一条欧拉回路。另外加入一种模式,如果开了,则后面的是各一次删一条。

 

由于开了之后是各一次删一条边,那么就只能是已一个点为中心来回走,不然删不掉所有的边。因此图就变成了两部分,一个是欧拉回路全删掉,一个是以一个点为中心的星图。

 

枚举星图的中心,然后把他所有相邻的边删掉,如果此时奇数点大于1,那么肯定不存在,因此中心肯定是欧拉的终点(奇数点)。

有两种情况:

1. 相邻的奇数点都放在星图

    如果欧拉图的奇数点等于1,该星图中心就必须也是奇数点。如果是0,则是偶数点。

2.欧拉图的奇数点为0,但是星图中心是奇数点,则需要从相邻的奇数点拿一个。

   枚举相邻的奇数点,看看是否可以跑出答案。

 

看上去好像是O(n^2*m),但由于枚举点+枚举相邻的点,一共只会枚举m条边,时间复杂度就是O(m*m)

 

 

using namespace std;
//int mod = 998244353;
int mod = 1e9+7;

int get_min(int a, int b){
	if(a==-1) return b;
	if(b==-1) return a;
	return min(a,b);
}

struct Edge{
	int a,b,c,next;
	int v;
	Edge(){v = 0;}
	Edge(int a, int b, int c, int next):a(a),b(b),c(c),next(next){v = 0;}
}e[N];

int p[N];
int tot;
int n,m;

void add(int a, int b){
	e[tot] = Edge(a,b,0,p[a]);
	p[a] = tot++;
}

vector<int> g[N];
int d[N], dd[N], v[N];

vector<int> ans;

void dfs(int t){
	for(int i = p[t]; i !=-1; i = e[i].next){
		if(e[i].c)continue;
		e[i].c = 1;
		e[i^1].c = 1;
		dfs(e[i].b);
	}
	ans.pb(t);
}

int sol(int idx){
	int c = 0;
	for(int i = 0; i < tot; i +=2){
		if(e[i].c==2)continue;
		e[i].c = 0;
		e[i^1].c = 0;
		c++;
	}
	dfs(idx);
	if(ans.size() != c + 1){
		ans.clear();
		return 0;
	}
	return 1;
}

bool check(int idx){
	int dn = 0;
	for(int i = 1; i <=n; ++i){
		if(d[i]%2 && i !=idx){
			++dn;
		}
		dd[i] = d[i];
	}

	for(int i = 0; i <tot; i++){
		e[i].c = 0;
	}

	int dn2 = 0;
	for(int i = p[idx]; i !=-1; i = e[i].next){
		int u = e[i].b;
		if(dd[u]%2){
			dn2++;
		}
	}
	if(dn-dn2>=2){
		return 0;
	}
	if(dn-dn2<=1){
		vector<int> x,nd;
		for(int i = p[idx]; i !=-1; i = e[i].next){
			int u = e[i].b;
			if(dd[u]%2){
				dd[u]--;
				dd[idx]--;
				e[i].c = 2;
				e[i^1].c = 2;
				nd.pb(u);
				x.pb(i);
			}
		}
		ans.clear();
		if((dn-dn2==0&&dd[idx]%2==0)||(dn-dn2==1&&dd[idx]%2)){
			if(sol(idx)){
				if(nd.size()){
					ans.pb(-1);
					for(int d : nd){
						ans.pb(d);
						ans.pb(idx);
					}
				}
				return 1;
			}
		}
		if(dn-dn2==0 && dd[idx]%2==0){
			for(int i : x){
				e[i].c = 0;
				e[i^1].c = 0;
				ans.clear();
				if(sol(idx)){
					if(nd.size()>1){
						ans.pb(-1);
						for(int d : nd){
							if(d==e[i].b)continue;
							ans.pb(d);
							ans.pb(idx);
						}
					}
					return 1;
				}
				e[i].c = 2;
				e[i^1].c = 2;
			}
		}
	}
	return 0;
}

int main(){
	cin>>n>>m;
	tot = 0;
	_clr(p);
	fr(i,0,m){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
		++d[u];
		++d[v];
	}
	for(int i = 1; i <=n;++i){
		if(check(i)){
			break;
		}
	}
	cout<<ans.size()<<endl;
	for(int t : ans){
		printf("%d ",t);
	}
	pf("\n");
}

 

/* make mpirun --use-hwthread-cpus -np 6 main mpirun --use-hwthread-cpus -np 6 -- main -NN 6 -dt 0.1 */ //MFEM #include "mfem.hpp" #include <fstream> #include <iostream> #include <algorithm> #include <iomanip> #include "Integ.hpp" using namespace std; using namespace mfem; #define mfemPrintf(...) { \ if (Mpi::Root()) { \ printf(__VA_ARGS__); \ } \ }//令mfemPrintf函数可用 const real_t PARAM_NU = 1.0; // viscosity const real_t PARAM_KAPPA = 1.0; // thermal diffusivity const real_t PARAM_BETA = 1.0; // thermal expansion coefficient //exampleC void uFun_ex(const Vector & x,real_t t, Vector & u) { real_t xi(x(0)); real_t yi(x(1)); real_t zi(x(2)); u(0) = yi*sin(t)*sin(t); u(1) = zi*sin(t)*sin(t); u(2) = xi*sin(t)*sin(t); } void gradu_exact(const Vector &xx,real_t t, Vector &u) { real_t x(xx(0)); real_t y(xx(1)); real_t z(xx(2)); // grad u1 u[0] = 0.0; u[1] = sin(t)*sin(t); u[2] = 0.0; // grad u2 u[3] = 0.0; u[4] = 0.0; u[5] = sin(t)*sin(t); // grad u3 u[6] = sin(t)*sin(t); u[7] = 0.0; u[8] = 0.0; } real_t pFun_ex(const Vector & x,real_t t) { real_t xi(x(0)); real_t yi(x(1)); real_t zi(x(2)); return (xi+yi+zi-1.5)*sin(t)*sin(t); } void fFun(const Vector & x,real_t t, Vector & f) { real_t xi(x(0)); real_t yi(x(1)); real_t zi(x(2)); f(0) = zi*pow(sin(t),4)+pow(sin(t),2)+2*yi*cos(t)*sin(t); f(1) = xi*pow(sin(t),4)+pow(sin(t),2)+2*zi*cos(t)*sin(t); f(2) = yi*pow(sin(t),4)+pow(sin(t),2)+2*xi*cos(t)*sin(t); } // 温度场的解析解和源项 real_t thetaFun_ex(const Vector & x, real_t t) { real_t xi(x(0)); real_t yi(x(1)); real_t zi(x(2)); return (xi + yi + zi - 1.5) * sin(t) * sin(t); } real_t psiFun(const Vector & x, real_t t) { real_t xi(x(0)); real_t yi(x(1)); real_t zi(x(2)); // 根据方程推导的源项 return (xi + yi + zi - 1.5) * (2 * sin(t) * cos(t)) + PARAM_KAPPA * 3 * sin(t) * sin(t) + (yi * sin(t) * sin(t) * sin(t) * sin(t) + zi * sin(t) * sin(t) * sin(t) * sin(t) + xi * sin(t) * sin(t) * sin(t) * sin(t)); } // 浮力项系数 class BuoyancyCoefficient : public VectorCoefficient { private: Coefficient &theta_coeff; Coefficient &beta_coeff; Vector gravity; public: BuoyancyCoefficient(int dim, Coefficient &theta_, Coefficient &beta_) : VectorCoefficient(dim), theta_coeff(theta_), beta_coeff(beta_) { gravity.SetSize(dim); gravity = 0.0; gravity(2) = -1.0; // 重力方向为负z轴 } virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip) { real_t theta_val = theta_coeff.Eval(T, ip); real_t beta_val = beta_coeff.Eval(T, ip); V.Set(beta_val * theta_val, gravity); } }; //向量函数的H1误差 real_t ComputeVectorGradError(ParGridFunction &sol, VectorCoefficient &exgrad, const IntegrationRule *irs[]) { ParFiniteElementSpace *fes = sol.ParFESpace(); real_t error = 0.0; const FiniteElement *fe; ElementTransformation *Tr; DenseMatrix grad; int intorder; int sdim = fes->GetMesh()->SpaceDimension(); int vdim = fes->GetVDim(); Vector vec(vdim * sdim); for (int i = 0; i < fes->GetNE(); i++) { fe = fes->GetFE(i); Tr = fes->GetElementTransformation(i); intorder = 2 * fe->GetOrder() + 3; // <-------- const IntegrationRule *ir; if (irs) { ir = irs[fe->GetGeomType()]; } else { ir = &(IntRules.Get(fe->GetGeomType(), intorder)); } for (int j = 0; j < ir->GetNPoints(); j++) { const IntegrationPoint &ip = ir->IntPoint(j); Tr->SetIntPoint(&ip); sol.GetVectorGradient(*Tr, grad); exgrad.Eval(vec, *Tr, ip); for (int d = 0; d < vdim; d++) { for (int k = 0; k < sdim; k++) { vec(d * sdim + k) -= grad(d, k); } } error += ip.weight * Tr->Weight() * (vec * vec); } } real_t glb_error = 0.0; MPI_Allreduce(&error, &glb_error, 1, MPITypeMap<real_t>::mpi_type, MPI_SUM, fes->GetComm()); return sqrt(glb_error); } // Function to compute the integral of a ParGridFunction and subtract its mean value void Zeromean(ParGridFunction &p) { ParFiniteElementSpace *p_space = p.ParFESpace(); ParLinearForm int_form(p_space); ConstantCoefficient one_coeff(1.0); int_form.AddDomainIntegrator(new DomainLFIntegrator(one_coeff)); int_form.Assemble(); real_t int_p = 0.0; real_t int_p_loc = InnerProduct(int_form, p); //使用 MPI 的 MPI_Allreduce 函数将所有进程中的局部积分结果 int_p_loc 进行全局归约(求和),并将结果存储在 int_p 中 MPI_Allreduce(&int_p_loc, &int_p, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); //mfemPrintf("Integral of p: %lg, ", int_p); ParGridFunction one_gf(p_space); one_gf.ProjectCoefficient(one_coeff); real_t vol_loc = InnerProduct(int_form, one_gf); real_t vol = 0.0; MPI_Allreduce(&vol_loc, &vol, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); real_t mean_p = int_p / vol; p.Add(-mean_p, one_gf); int_p_loc = InnerProduct(int_form, p); MPI_Allreduce(&int_p_loc, &int_p, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); //mfemPrintf("after modification: %lg\n", int_p); } // 改进的预条件器类,处理速度-压力-温度三场耦合 class BoussinesqPC : public mfem::Solver { private: ParFiniteElementSpace *V_space; ParFiniteElementSpace *P_space; ParFiniteElementSpace *T_space; BlockOperator &block_op; Array<int> &block_trueOffsets; // 速度块预条件器组件 HypreParMatrix *pc_Fmat; // 修改名称,添加pc_前缀 HypreBoomerAMG *prec_F; CGSolver *solver_F; // 压力Schur补预条件器组件 HypreParMatrix *pc_Kpmat; // 修改名称,添加pc_前缀 HypreBoomerAMG *prec_Kp; CGSolver *solver_Kp; HypreParMatrix *pc_Mpmat; // 修改名称,添加pc_前缀 HypreDiagScale *prec_Mp; CGSolver *solver_Mp; // 温度Schur补预条件器组件 HypreParMatrix *pc_Ktmat; // 修改名称,添加pc_前缀 HypreBoomerAMG *prec_Kt; CGSolver *solver_Kt; HypreParMatrix *pc_Mtmat; // 修改名称,添加pc_前缀 HypreDiagScale *prec_Mt; CGSolver *solver_Mt; // 耦合项矩阵 HypreParMatrix *pc_Gmat; // 修改名称,添加pc_前缀 real_t dt_, nu_, kappa_, beta_; public: BoussinesqPC(ParFiniteElementSpace *V_space_, ParFiniteElementSpace *P_space_, ParFiniteElementSpace *T_space_, BlockOperator &block_op_, Array<int> &offsets_, real_t dt_, real_t nu_, real_t kappa_, real_t beta_) : Solver(offsets_[3]), V_space(V_space_), P_space(P_space_), T_space(T_space_), block_op(block_op_), block_trueOffsets(offsets_), dt_(dt_), nu_(nu_), kappa_(kappa_), beta_(beta_), pc_Fmat(nullptr), pc_Kpmat(nullptr), pc_Mpmat(nullptr), pc_Ktmat(nullptr), pc_Mtmat(nullptr), pc_Gmat(nullptr) { // 初始化速度块预条件器 ConstantCoefficient oneondt(1.0 / dt_); ConstantCoefficient nu_coeff(nu_); ParBilinearForm F_varf(V_space); F_varf.AddDomainIntegrator(new VectorMassIntegrator(oneondt)); F_varf.AddDomainIntegrator(new VectorDiffusionIntegrator(nu_coeff)); F_varf.Assemble(); F_varf.Finalize(); pc_Fmat = F_varf.ParallelAssemble(); if (pc_Fmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Fmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } prec_F = new HypreBoomerAMG(*pc_Fmat); prec_F->SetPrintLevel(0); solver_F = new CGSolver(MPI_COMM_WORLD); solver_F->SetPreconditioner(*prec_F); solver_F->SetOperator(*pc_Fmat); solver_F->SetRelTol(1e-5); solver_F->SetMaxIter(100); solver_F->SetPrintLevel(0); // 初始化压力Schur补预条件器 ParBilinearForm Mp_varf(P_space); Mp_varf.AddDomainIntegrator(new MassIntegrator); Mp_varf.Assemble(); Mp_varf.Finalize(); pc_Mpmat = Mp_varf.ParallelAssemble(); if (pc_Mpmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Mpmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } prec_Mp = new HypreDiagScale(*pc_Mpmat); solver_Mp = new CGSolver(MPI_COMM_WORLD); solver_Mp->SetPreconditioner(*prec_Mp); solver_Mp->SetOperator(*pc_Mpmat); solver_Mp->SetRelTol(1e-5); solver_Mp->SetMaxIter(100); solver_Mp->SetPrintLevel(0); ParBilinearForm Kp_varf(P_space); Kp_varf.AddDomainIntegrator(new DiffusionIntegrator); Kp_varf.Assemble(); Array<int> ess_vdofs_p; if(Mpi::Root()) { ess_vdofs_p.Append(0); } Kp_varf.EliminateVDofs(ess_vdofs_p); Kp_varf.Finalize(); pc_Kpmat = Kp_varf.ParallelAssemble(); if (pc_Kpmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Kpmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } prec_Kp = new HypreBoomerAMG(*pc_Kpmat); prec_Kp->SetPrintLevel(0); solver_Kp = new CGSolver(MPI_COMM_WORLD); solver_Kp->SetPreconditioner(*prec_Kp); solver_Kp->SetOperator(*pc_Kpmat); solver_Kp->SetRelTol(1e-5); solver_Kp->SetMaxIter(100); solver_Kp->SetPrintLevel(0); // 初始化温度Schur补预条件器 ParBilinearForm Mt_varf(T_space); Mt_varf.AddDomainIntegrator(new MassIntegrator); Mt_varf.Assemble(); Mt_varf.Finalize(); pc_Mtmat = Mt_varf.ParallelAssemble(); if (pc_Mtmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Mtmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } prec_Mt = new HypreDiagScale(*pc_Mtmat); solver_Mt = new CGSolver(MPI_COMM_WORLD); solver_Mt->SetPreconditioner(*prec_Mt); solver_Mt->SetOperator(*pc_Mtmat); solver_Mt->SetRelTol(1e-5); solver_Mt->SetMaxIter(100); solver_Mt->SetPrintLevel(0); ParBilinearForm Kt_varf(T_space); Kt_varf.AddDomainIntegrator(new DiffusionIntegrator); Kt_varf.Assemble(); Array<int> ess_vdofs_t; if(Mpi::Root()) { ess_vdofs_t.Append(0); } Kt_varf.EliminateVDofs(ess_vdofs_t); Kt_varf.Finalize(); pc_Ktmat = Kt_varf.ParallelAssemble(); if (pc_Ktmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Ktmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } prec_Kt = new HypreBoomerAMG(*pc_Ktmat); prec_Kt->SetPrintLevel(0); solver_Kt = new CGSolver(MPI_COMM_WORLD); solver_Kt->SetPreconditioner(*prec_Kt); solver_Kt->SetOperator(*pc_Ktmat); solver_Kt->SetRelTol(1e-5); solver_Kt->SetMaxIter(100); solver_Kt->SetPrintLevel(0); // 初始化浮力耦合项矩阵 Vector gravity(3); gravity = 0.0; gravity(2) = -1.0; // 重力方向为负z轴 VectorConstantCoefficient g_coeff(gravity); ParMixedBilinearForm G_varf(T_space, V_space); G_varf.AddDomainIntegrator(new VectorMassIntegrator(g_coeff)); G_varf.Assemble(); G_varf.Finalize(); pc_Gmat = G_varf.ParallelAssemble(); if (pc_Gmat == nullptr) { if (Mpi::Root()) { std::cerr << "错误: pc_Gmat 矩阵装配失败!" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } }; ~BoussinesqPC() { delete pc_Fmat; delete pc_Kpmat; delete pc_Mpmat; delete pc_Ktmat; delete pc_Mtmat; delete pc_Gmat; delete prec_F; delete solver_F; delete prec_Kp; delete solver_Kp; delete prec_Mp; delete solver_Mp; delete prec_Kt; delete solver_Kt; delete prec_Mt; delete solver_Mt; } void Mult(const mfem::Vector &x, mfem::Vector &y) const { StopWatch timer; Vector v_in(x.GetData() + block_trueOffsets[0], block_trueOffsets[1] - block_trueOffsets[0]); Vector p_in(x.GetData() + block_trueOffsets[1], block_trueOffsets[2] - block_trueOffsets[1]); Vector t_in(x.GetData() + block_trueOffsets[2], block_trueOffsets[3] - block_trueOffsets[2]); Vector v_out(y.GetData() + block_trueOffsets[0], block_trueOffsets[1] - block_trueOffsets[0]); Vector p_out(y.GetData() + block_trueOffsets[1], block_trueOffsets[2] - block_trueOffsets[1]); Vector t_out(y.GetData() + block_trueOffsets[2], block_trueOffsets[3] - block_trueOffsets[2]); // 第一步:求解温度Schur补系统 Vector t_temp(t_in.Size()); timer.Clear(); timer.Start(); solver_Kt->Mult(t_in, t_temp); pc_Mtmat->Mult(t_temp, t_temp); solver_Mt->Mult(t_temp, t_out); timer.Stop(); // 第二步:求解压力Schur补系统 Vector p_temp(p_in.Size()); timer.Clear(); timer.Start(); solver_Kp->Mult(p_in, p_temp); pc_Mpmat->Mult(p_temp, p_temp); solver_Mp->Mult(p_temp, p_out); timer.Stop(); // 第三步:求解速度系统,考虑浮力耦合 Vector v_temp(v_in.Size()); // 添加浮力项贡献 Vector Gt_result(v_temp.Size()); if (pc_Gmat != nullptr) { pc_Gmat->Mult(t_out, Gt_result); v_temp.Add(-beta_, Gt_result); } else { if (Mpi::Root()) { std::cerr << "警告: pc_Gmat 为空,跳过浮力项" << std::endl; } } // 添加压力项贡献 - 修复这里 Operator& Bt_op = block_op.GetBlock(0, 1); Vector Bp_result(v_temp.Size()); Bt_op.Mult(p_out, Bp_result); // 直接使用运算符,不进行dynamic_cast v_temp.Add(-1.0, Bp_result); timer.Clear(); timer.Start(); solver_F->Mult(v_temp, v_out); timer.Stop(); }; void SetOperator(const Operator &op) {}; }; int main(int argc, char *argv[]) { StopWatch chrono; // 1. Initialize MPI and HYPRE. Mpi::Init(argc, argv); int myid = Mpi::WorldRank(); Hypre::Init(); bool verbose = (myid == 0); // 2. Parse command-line options. const char *mesh_file = "../data/star.mesh"; int ref_levels = -1; int order = 1; real_t dt = 0.05; real_t t_final = 0.05; int NN = 4;//空间每个坐标轴划分为NN等分 /* make NS_1 mpirun --use-hwthread-cpus -np 6 NS_1 */ bool par_format = false; bool pa = false; const char *device_config = "cpu"; bool visualization = 1; bool adios2 = false; OptionsParser args(argc, argv); args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use."); args.AddOption(&ref_levels, "-r", "--refine", "Number of times to refine the mesh uniformly."); args.AddOption(&order, "-o", "--order", "Finite element order (polynomial degree)."); args.AddOption(&par_format, "-pf", "--parallel-format", "-sf", "--serial-format", "Format to use when saving the results for VisIt."); args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa", "--no-partial-assembly", "Enable Partial Assembly."); args.AddOption(&device_config, "-d", "--device", "Device configuration string, see Device::Configure()."); args.AddOption(&visualization, "-vis", "--visualization", "-no-vis", "--no-visualization", "Enable or disable GLVis visualization."); args.AddOption(&adios2, "-adios2", "--adios2-streams", "-no-adios2", "--no-adios2-streams", "Save data using adios2 streams."); args.AddOption(&dt, "-dt", "--dt", "dt."); args.AddOption(&NN, "-NN", "--NN", "NN."); args.AddOption(&t_final, "-t_final", "--t_final", "t_final."); args.Parse(); if (!args.Good()) { if (verbose) { args.PrintUsage(cout); } return 1; } if (verbose) { args.PrintOptions(cout); } int nsteps = ceil(t_final / dt); dt = t_final / nsteps; // 3. Enable hardware devices such as GPUs, and programming models such as // CUDA, OCCA, RAJA and OpenMP based on command line options. Device device(device_config); if (myid == 0) { device.Print(); } //Mesh int Nx = NN, Ny = NN, Nz = NN; real_t Sx = 1.0, Sy = 1.0, Sz = 1.0; Mesh mesha = Mesh::MakeCartesian3D(Nx, Ny, Nz, Element::TETRAHEDRON, Sx, Sy, Sz); Mesh *mesh=&mesha; int dim = mesh->Dimension(); ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh); pmesh->PrintInfo(std::cout); //delete mesh; //FiniteElementSpace FiniteElementCollection *P2(new H1_FECollection(order+1, dim)); FiniteElementCollection *P1(new H1_FECollection(order)); ParFiniteElementSpace *V_space = new ParFiniteElementSpace(pmesh, P2, dim); ParFiniteElementSpace *P_space = new ParFiniteElementSpace(pmesh, P1); ParFiniteElementSpace *T_space = new ParFiniteElementSpace(pmesh, P1); // 温度空间 HYPRE_BigInt dimR = V_space->GlobalTrueVSize(); HYPRE_BigInt dimW = P_space->GlobalTrueVSize();//查看全局的真实向量自由度(True Vector DoFs)总数 HYPRE_BigInt dimT = T_space->GlobalTrueVSize(); if (verbose)//若当前进程是主进程,查看维数 { std::cout << "***********************************************************\n"; std::cout << "dim(R) = " << dimR << "\n"; std::cout << "dim(W) = " << dimW << "\n"; std::cout << "dim(T) = " << dimT << "\n"; std::cout << "dim(R+W+T) = " << dimR + dimW + dimT << "\n"; std::cout << "***********************************************************\n"; } //Define the coefficients, analytical solution, and rhs of the PDE. ConstantCoefficient k(1.0); ConstantCoefficient nu(PARAM_NU); ConstantCoefficient kappa(PARAM_KAPPA); ConstantCoefficient beta_coeff(PARAM_BETA); ConstantCoefficient m_one(-1.0); ConstantCoefficient oneondt1(1.0 / dt); VectorFunctionCoefficient fcoeff(dim, fFun); VectorFunctionCoefficient ucoeff(dim, uFun_ex); FunctionCoefficient pcoeff(pFun_ex); FunctionCoefficient thetacoeff(thetaFun_ex); FunctionCoefficient psicoeff(psiFun); Array<int> block_Offsets(4);//分块方法 block_Offsets[0] = 0; block_Offsets[1] = V_space->GetTrueVSize(); block_Offsets[2] = P_space->GetTrueVSize(); block_Offsets[3] = T_space->GetTrueVSize(); block_Offsets.PartialSum(); //存储解向量和右端向量,每个时间步都更新 Vector rhs(block_Offsets[3]); Vector sol(block_Offsets[3]); Vector rhs_u(rhs.GetData(), block_Offsets[1] - block_Offsets[0]);//使用rhs的内存,不分配新的内存 Vector rhs_p(rhs.GetData() + block_Offsets[1], block_Offsets[2] - block_Offsets[1]); Vector rhs_t(rhs.GetData() + block_Offsets[2], block_Offsets[3] - block_Offsets[2]); Vector sol_u(sol.GetData(), block_Offsets[1] - block_Offsets[0]); Vector sol_p(sol.GetData() + block_Offsets[1], block_Offsets[2] - block_Offsets[1]); Vector sol_t(sol.GetData() + block_Offsets[2], block_Offsets[3] - block_Offsets[2]); //使用低阶格式得到前面几步的值 ParGridFunction uh_0(V_space),ph(P_space),th(T_space); ParGridFunction beta_kn(V_space),gamma_kn(V_space); ucoeff.SetTime(0.0); pcoeff.SetTime(0.0); thetacoeff.SetTime(0.0); real_t t = 0.0; uh_0.ProjectCoefficient(ucoeff);//设置初值 th.ProjectCoefficient(thetacoeff); chrono.Clear(); chrono.Start(); real_t errp=0.0; real_t errt=0.0; Array<int> ess_bdr(mesh->bdr_attributes.Max()); ess_bdr = 1; // Dirichlet boundary on all boundary faces ParBilinearForm F_old_varf(V_space); F_old_varf.AddDomainIntegrator(new VectorMassIntegrator(oneondt1)); F_old_varf.Assemble(); // 在时间循环外声明矩阵指针,使用不同的名称 HypreParMatrix *main_Fmat = nullptr; HypreParMatrix *main_Bmat = nullptr; HypreParMatrix *main_Btmat = nullptr; HypreParMatrix *main_Cmat = nullptr; HypreParMatrix *main_Gmat = nullptr; HypreParMatrix *main_Gtmat = nullptr; ParGridFunction uh_n(V_space),uh(V_space),theta_n(T_space),theta(T_space); uh_n=uh_0; theta_n=th; if (verbose) { std::cout << "开始时间循环..." << std::endl; } for (int n = 0; n < nsteps; n++) { if (verbose && myid == 0) { std::cout << "时间步 " << n + 1 << "/" << nsteps << std::endl; } // 删除已存在的矩阵 if (main_Fmat) { delete main_Fmat; main_Fmat = nullptr; } if (main_Bmat) { delete main_Bmat; main_Bmat = nullptr; } if (main_Btmat) { delete main_Btmat; main_Btmat = nullptr; } if (main_Cmat) { delete main_Cmat; main_Cmat = nullptr; } if (main_Gmat) { delete main_Gmat; main_Gmat = nullptr; } if (main_Gtmat) { delete main_Gtmat; main_Gtmat = nullptr; } if(n>0){ uh_n=uh; theta_n=theta; } ucoeff.SetTime(t+dt); pcoeff.SetTime(t+dt); thetacoeff.SetTime(t+dt); uh=0.0; theta=0.0; uh.ProjectBdrCoefficient(ucoeff, ess_bdr); theta.ProjectBdrCoefficient(thetacoeff, ess_bdr); beta_kn=uh_n; gamma_kn=uh_n; fcoeff.SetTime(t+dt); ParLinearForm f_form(V_space); f_form.AddDomainIntegrator(new VectorDomainLFIntegrator(fcoeff)); f_form.AddDomainIntegrator(new VectorConvectionLFIntegrator(gamma_kn,-1.0)); f_form.Assemble(); F_old_varf.AddMult(beta_kn, f_form, 1.0);//将F_old*beta_kn(矩阵乘向量)加到f_form上 // 添加浮力项 BuoyancyCoefficient buoyancy_coeff(dim, thetacoeff, beta_coeff); ParLinearForm buoyancy_form(V_space); buoyancy_form.AddDomainIntegrator(new VectorDomainLFIntegrator(buoyancy_coeff)); buoyancy_form.Assemble(); f_form += buoyancy_form; ParLinearForm g_form(P_space); g_form.Assemble(); psicoeff.SetTime(t+dt); ParLinearForm psi_form(T_space); psi_form.AddDomainIntegrator(new DomainLFIntegrator(psicoeff)); psi_form.Assemble(); //Bilinear forms ParBilinearForm F_varf(V_space); F_varf.AddDomainIntegrator(new VectorDiffusionIntegrator(nu)); F_varf.AddDomainIntegrator(new VectorMassIntegrator(oneondt1)); F_varf.Assemble(); ParMixedBilinearForm B_varf(V_space,P_space); B_varf.AddDomainIntegrator(new VectorDivergenceIntegrator(m_one)); B_varf.Assemble(); ParBilinearForm C_varf(T_space); C_varf.AddDomainIntegrator(new DiffusionIntegrator(kappa)); C_varf.AddDomainIntegrator(new MassIntegrator(oneondt1)); C_varf.Assemble(); Vector gravity(3); gravity = 0.0; gravity(2) = -1.0; VectorConstantCoefficient g_coeff(gravity); ParMixedBilinearForm G_varf(T_space,V_space); G_varf.AddDomainIntegrator(new VectorMassIntegrator(g_coeff)); G_varf.Assemble(); // Dirichlet boundary F_varf.EliminateEssentialBC(ess_bdr, uh, f_form); B_varf.EliminateTrialEssentialBC(ess_bdr, uh, g_form); C_varf.EliminateEssentialBC(ess_bdr, theta, psi_form); F_varf.Finalize(); B_varf.Finalize(); C_varf.Finalize(); G_varf.Finalize(); // 创建新矩阵 main_Fmat = F_varf.ParallelAssemble(); main_Bmat = B_varf.ParallelAssemble(); main_Btmat = main_Bmat->Transpose(); main_Cmat = C_varf.ParallelAssemble(); main_Gmat = G_varf.ParallelAssemble(); main_Gtmat = main_Gmat->Transpose(); // 检查矩阵是否成功创建 if (main_Fmat == nullptr || main_Bmat == nullptr || main_Cmat == nullptr || main_Gmat == nullptr || main_Btmat == nullptr || main_Gtmat == nullptr) { if (myid == 0) { std::cerr << "错误: 矩阵装配失败!" << std::endl; if (main_Fmat == nullptr) std::cerr << "main_Fmat is null" << std::endl; if (main_Bmat == nullptr) std::cerr << "main_Bmat is null" << std::endl; if (main_Btmat == nullptr) std::cerr << "main_Btmat is null" << std::endl; if (main_Cmat == nullptr) std::cerr << "main_Cmat is null" << std::endl; if (main_Gmat == nullptr) std::cerr << "main_Gmat is null" << std::endl; if (main_Gtmat == nullptr) std::cerr << "main_Gtmat is null" << std::endl; } MPI_Abort(MPI_COMM_WORLD, 1); } { BlockOperator block_op(block_Offsets); block_op.SetBlock(0, 0, main_Fmat); block_op.SetBlock(0, 1, main_Btmat); block_op.SetBlock(0, 2, main_Gtmat); block_op.SetBlock(1, 0, main_Bmat); block_op.SetBlock(2, 0, main_Gmat); block_op.SetBlock(2, 2, main_Cmat); sol = 0.0;rhs=0.0; f_form.ParallelAssemble(rhs_u); g_form.ParallelAssemble(rhs_p); psi_form.ParallelAssemble(rhs_t);//组装右端向量 // compatibility condition Vector one_vec(rhs_p.Size()); one_vec = 1.0; real_t rhs_p_sum_loc = InnerProduct(rhs_p, one_vec); real_t rhs_p_sum; MPI_Allreduce(&rhs_p_sum_loc, &rhs_p_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); rhs_p -= (rhs_p_sum) / P_space->GlobalTrueVSize(); BoussinesqPC prec(V_space, P_space, T_space, block_op, block_Offsets, dt, PARAM_NU, PARAM_KAPPA, PARAM_BETA); FGMRESSolver solver(MPI_COMM_WORLD); solver.SetRelTol(1e-12); solver.SetMaxIter(500); solver.SetOperator(block_op); solver.SetPreconditioner(prec); solver.SetPrintLevel(1); solver.Mult(rhs, sol); uh.Distribute(sol_u); ph.Distribute(sol_p); theta.Distribute(sol_t);//提取解 if(myid == 0){ cout <<"t = "<< t+dt << endl; } t += dt; } } // 在程序最后统一清理矩阵 delete main_Fmat; delete main_Bmat; delete main_Btmat; delete main_Cmat; delete main_Gmat; delete main_Gtmat; Zeromean(ph); errp += pow(ph.ComputeL2Error(pcoeff),2); errt += pow(theta.ComputeL2Error(thetacoeff),2); //计算误差 //H1误差 int gradu_dim = dim*dim; VectorFunctionCoefficient gradu_exact_coeff(gradu_dim, gradu_exact); gradu_exact_coeff.SetTime(t); real_t GradError = ComputeVectorGradError(uh, gradu_exact_coeff,nullptr); //计算L2误差 real_t err_u; err_u = uh.ComputeL2Error(ucoeff); errp=sqrt(errp*dt); real_t err_p=ph.ComputeL2Error(pcoeff); errt=sqrt(errt*dt); real_t err_theta=theta.ComputeL2Error(thetacoeff); int order_quad = max(2, 2*order+1); const IntegrationRule *irs[Geometry::NumGeom]; for (int i=0; i < Geometry::NumGeom; ++i) { irs[i] = &(IntRules.Get(i, order_quad)); } real_t norm_u = ComputeGlobalLpNorm(2, ucoeff, *pmesh, irs); chrono.Stop(); if (myid == 0) { cout <<"t = "<< t << " || u_h - u_ex || = " << err_u << endl; cout <<"t = "<< t << " err_p_L2 = " << err_p << endl; cout <<"t = "<< t << " err_theta_L2 = " << err_theta << endl; cout <<"t= "<< t << " H1_error = "<< GradError <<endl; cout << "t = "<< t <<" norm_u = "<< norm_u << "\n"; std::cout << "It took " << chrono.RealTime() << "s. \n"; std::ofstream out_file("parameters1.txt", std::ios::app); if (out_file.is_open()) { out_file << "\n##################### " << "\n"; out_file << std::scientific << std::setprecision(10); out_file << "k = 1" << "\n"; out_file << "T = " << t_final << "\n"; out_file << "dt = " << dt << "\n"; out_file << "NN = " << NN << "\n"; out_file << "err_u = " << err_u << "\n"; out_file << "err_p_L2 = " << err_p << "\n"; out_file << "err_theta_L2 = " << err_theta << "\n"; out_file << "H1_error = "<< GradError << "\n"; out_file << "It took " << chrono.RealTime() << "\n"; out_file.close(); std::cout << "参数已保存到 parameters1.txt" << std::endl; } else { std::cerr << "错误:无法打开文件!" << std::endl; } } // Free the used memory. delete V_space; delete P_space; delete T_space; delete P2; delete P1; delete pmesh; return 0; }该代码可以编译但不能运行,运行后出现下面的报错Options used: --mesh ../data/star.mesh --refine -1 --order 1 --serial-format --no-partial-assembly --device cpu --visualization --no-adios2-streams --dt 0.05 --NN 4 --t_final 0.05 Device configuration: cpu Memory configuration: host-std Parallel Mesh Stats: minimum average maximum total vertices 48 62 77 125 edges 268 302 336 604 faces 411 432 453 864 elements 191 192 193 384 neighbors 1 1 1 minimum maximum h 0.280616 0.280616 kappa 2.41421 2.41421 *********************************************************** dim(R) = 2187 dim(W) = 125 dim(T) = 125 dim(R+W+T) = 2437 *********************************************************** 开始时间循环... 时间步 1/1 [LAPTOP-QL5QOURA:00495] *** Process received signal *** [LAPTOP-QL5QOURA:00495] Signal: Segmentation fault (11) [LAPTOP-QL5QOURA:00495] Signal code: Address not mapped (1) [LAPTOP-QL5QOURA:00495] Failing at address: (nil) [LAPTOP-QL5QOURA:00496] *** Process received signal *** [LAPTOP-QL5QOURA:00496] Signal: Segmentation fault (11) [LAPTOP-QL5QOURA:00496] Signal code: Address not mapped (1) [LAPTOP-QL5QOURA:00496] Failing at address: (nil) [LAPTOP-QL5QOURA:00495] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x45330)[0x7e1f49645330] [LAPTOP-QL5QOURA:00495] [ 1] ./NS_1(+0x44ca78)[0x5675352dba78] [LAPTOP-QL5QOURA:00495] [ 2] ./NS_1(+0x44179f)[0x5675352d079f] [LAPTOP-QL5QOURA:00495] [ 3] ./NS_1(+0x4986ed)[0x5675353276ed] [LAPTOP-QL5QOURA:00495] [ 4] ./NS_1(+0xa06ef)[0x567534f2f6ef] [LAPTOP-QL5QOURA:00495] [ 5] [LAPTOP-QL5QOURA:00496] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x45330)[0x7e6862445330] [LAPTOP-QL5QOURA:00496] [ 1] ./NS_1(+0x44ca78)[0x555f7df7ea78] [LAPTOP-QL5QOURA:00496] [ 2] ./NS_1(+0x44179f)[0x555f7df7379f] [LAPTOP-QL5QOURA:00496] [ 3] ./NS_1(+0x4986ed)[0x555f7dfca6ed] [LAPTOP-QL5QOURA:00496] [ 4] ./NS_1(+0xa06ef)[0x555f7dbd26ef] [LAPTOP-QL5QOURA:00496] [ 5] /lib/x86_64-linux-gnu/libc.so.6(+0x2a1ca)[0x7e686242a1ca] [LAPTOP-QL5QOURA:00496] [ 6] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x8b)[0x7e686242a28b] [LAPTOP-QL5QOURA:00496] [ 7] ./NS_1(+0xa7e15)[0x555f7dbd9e15] [LAPTOP-QL5QOURA:00496] *** End of error message *** /lib/x86_64-linux-gnu/libc.so.6(+0x2a1ca)[0x7e1f4962a1ca] [LAPTOP-QL5QOURA:00495] [ 6] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x8b)[0x7e1f4962a28b] [LAPTOP-QL5QOURA:00495] [ 7] ./NS_1(+0xa7e15)[0x567534f36e15] [LAPTOP-QL5QOURA:00495] *** End of error message *** -------------------------------------------------------------------------- Primary job terminated normally, but 1 process returned a non-zero exit code. Per user-direction, the job has been aborted. -------------------------------------------------------------------------- -------------------------------------------------------------------------- mpirun noticed that process rank 0 with PID 0 on node LAPTOP-QL5QOURA exited on signal 11 (Segmentation fault). --------------------------------------------------------------------------给我提供详细的修改方案使其可以运行
09-20
geo_model.set_active_grids,from gempy.core.data import Surfaced在我的gempy中没有这些功能,我的gempy信息如下:F:\pythonProject\gempy-main.venv\Scripts\python.exe F:\pycharm\3d1.py Setting Backend To: AvailableBackends.numpy Help on package gempy_viewer: NAME gempy_viewer PACKAGE CONTENTS API (package) DEP (package) _version core (package) modules (package) optional_dependencies FUNCTIONS plot_2d(model: gempy.core.data.geo_model.GeoModel, n_axis=None, section_names: list = None, cell_number: Union[int, list[int], str, list[str], NoneType] = None, direction: Union[str, list[str], NoneType] = 'y', series_n: Union[int, List[int]] = 0, legend: bool = True, ve=1, block=None, override_regular_grid=None, kwargs_topography=None, kwargs_lithology=None, kwargs_scalar_field=None, **kwargs) -> gempy_viewer.modules.plot_2d.visualization_2d.Plot2D Plot 2-D sections of the geomodel. This function plots cross-sections either based on custom section traces or cell numbers in the xyz directions. Options are provided to plot lithology blocks, scalar fields, or rendered surface lines. Input data and topography can be included. Args: model (GeoModel): Geomodel object with solutions. n_axis (Optional[int]): Subplot axis for multiple sections. section_names (Optional[List[str]]): Names of predefined custom section traces. cell_number (Optional[Union[int, List[int], str, List[str]]]): Position of the array to plot. direction (Optional[Union[str, List[str]]]): Cartesian direction to be plotted (xyz). series_n (Union[int, List[int]]): Number of the scalar field. legend (bool): If True, plot legend. Defaults to True. ve (float): Vertical exaggeration. Defaults to 1. block (Optional[np.ndarray]): Deprecated. Use regular grid instead. override_regular_grid (Optional[np.ndarray]): Numpy array of the size of model.grid.regular_grid. If provided, the regular grid will be overridden by this array. kwargs_topography (Optional[dict]): Additional keyword arguments for topography. * fill_contour: Fill contour flag. * hillshade (bool): Calculate and add hillshading using elevation data. * azdeg (float): Azimuth of sun for hillshade. - altdeg (float): Altitude in degrees of sun for hillshade. kwargs_lithology (Optional[dict]): Additional keyword arguments for lithology. kwargs_scalar_field (Optional[dict]): Additional keyword arguments for scalar field. Keyword Args: show_block (bool): If True and the model has been computed, plot cross section of the final model. show_values (bool): If True and the model has been computed, plot cross section of the value. show (bool): Call matplotlib show. Defaults to True. show_data (bool): Show original input data. Defaults to True. show_results (bool): If False, override show lithology, scalar field, and values. Defaults to True. show_lith (bool): Show lithological block volumes. Defaults to True. show_scalar (bool): Show scalar field isolines. Defaults to False. show_boundaries (bool): Show surface boundaries as lines. Defaults to True. show_topography (bool): Show topography on plot. Defaults to False. show_section_traces (bool): Show section traces. Defaults to True. Returns: gempy.plot.visualization_2d.Plot2D: Plot2D object. plot_3d(model: gempy.core.data.geo_model.GeoModel, plotter_type: str = 'basic', active_scalar_field: Optional[str] = None, ve: Optional[float] = None, topography_scalar_type: gempy_viewer.core.scalar_data_type.TopographyDataType = <TopographyDataType.GEOMAP: 2>, kwargs_pyvista_bounds: Optional[dict] = None, kwargs_plot_structured_grid: Optional[dict] = None, kwargs_plot_topography: Optional[dict] = None, kwargs_plot_data: Optional[dict] = None, kwargs_plotter: Optional[dict] = None, kwargs_plot_surfaces: Optional[dict] = None, image: bool = False, show: bool = True, transformed_data: bool = False, **kwargs) -> gempy_viewer.modules.plot_3d.vista.GemPyToVista Plot 3-D geomodel. Args: model (GeoModel): Geomodel object with solutions. plotter_type (str): Type of plotter to use. Defaults to 'basic'. active_scalar_field (Optional[str]): Active scalar field for the plot. ve (Optional[float]): Vertical exaggeration. topography_scalar_type (TopographyDataType): Type of topography scalar data. Defaults to TopographyDataType.GEOMAP. kwargs_pyvista_bounds (Optional[dict]): Additional keyword arguments for PyVista bounds. kwargs_plot_structured_grid (Optional[dict]): Additional keyword arguments for plotting the structured grid. kwargs_plot_topography (Optional[dict]): Additional keyword arguments for plotting the topography. kwargs_plot_data (Optional[dict]): Additional keyword arguments for plotting data. kwargs_plotter (Optional[dict]): Additional keyword arguments for the plotter. kwargs_plot_surfaces (Optional[dict]): Additional keyword arguments for plotting surfaces. image (bool): If True, saves the plot as an image. Defaults to False. show (bool): If True, displays the plot. Defaults to True. transformed_data (bool): If True, uses transformed data for plotting. Defaults to False. **kwargs: Additional keyword arguments. Returns: GemPyToVista: Object for 3D plotting in GemPy. plot_section_traces(model: gempy.core.data.geo_model.GeoModel, section_names: list[str] = None) Plot section traces of section grid in 2-D topview (xy). plot_stereonet(self, litho=None, planes=True, poles=True, single_plots=False, show_density=False) plot_topology(regular_grid: gempy.core.data.grid_modules.grid_types.RegularGrid, edges, centroids, direction='y', ax=None, scale=True, label_kwargs=None, edge_kwargs=None) Plot the topology adjacency graph in 2-D. Args: geo_model ([type]): GemPy geomodel instance. edges (Set[Tuple[int, int]]): Set of topology edges. centroids (Dict[int, Array[int, 3]]): Dictionary of topology id's and their centroids. direction (Union["x", "y", "z", optional): Section direction. Defaults to "y". label_kwargs (dict, optional): Keyword arguments for topology labels. Defaults to None. edge_kwargs (dict, optional): Keyword arguments for topology edges. Defaults to None. DATA __all__ = ['plot_2d', 'plot_3d', 'plot_section_traces', 'plot_topology... VERSION 2024.2.0.2 FILE f:\pythonproject\gempy-main.venv\lib\site-packages\gempy_viewer\__init__.py Help on package gempy.API in gempy: NAME gempy.API - # Initialization API PACKAGE CONTENTS _version compute_API examples_generator faults_API gp2_gp3_compatibility (package) grid_API implicit_functions initialization_API io_API map_stack_to_surfaces_API FUNCTIONS add_orientations(geo_model: gempy.core.data.geo_model.GeoModel, x: Sequence[float], y: Sequence[float], z: Sequence[float], elements_names: Sequence[str], pole_vector: Optional[Sequence[numpy.ndarray]] = None, orientation: Optional[Sequence[numpy.ndarray]] = None, nugget: Optional[Sequence[float]] = None) -> gempy.core.data.structural_frame.StructuralFrame Add orientation data to the geological model. This function adds orientation data to the specified geological elements in the model. The orientation can be provided directly as pole vectors or as orientation angles (azimuth, dip, polarity). Optional nugget values can also be specified for each orientation point. Args: geo_model (GeoModel): The geological model to which the orientations will be added. x (Sequence[float]): Sequence of x-coordinates for the orientation points. y (Sequence[float]): Sequence of y-coordinates for the orientation points. z (Sequence[float]): Sequence of z-coordinates for the orientation points. elements_names (Sequence[str]): Sequence of element names corresponding to each orientation point. pole_vector (Optional[Sequence[np.ndarray]]): Sequence of pole vectors for the orientation points. orientation (Optional[Sequence[np.ndarray]]): Sequence of orientation angles (azimuth, dip, polarity) for the orientation points. nugget (Optional[Sequence[float]]): Sequence of nugget values for each orientation point. If not provided, a default value will be used for all points. Returns: StructuralFrame: The updated structural frame of the geological model. Raises: ValueError: If neither pole_vector nor orientation is provided, or if the length of the nugget sequence does not match the lengths of the other input sequences. add_structural_group(model: gempy.core.data.geo_model.GeoModel, group_index: int, structural_group_name: str, elements: list[gempy.core.data.structural_element.StructuralElement], structural_relation: gempy_engine.core.data.stack_relation_type.StackRelationType, fault_relations: gempy.core.data.structural_group.FaultsRelationSpecialCase = <FaultsRelationSpecialCase.OFFSET_ALL: 3>) -> gempy.core.data.structural_frame.StructuralFrame add_surface_points(geo_model: gempy.core.data.geo_model.GeoModel, x: Sequence[float], y: Sequence[float], z: Sequence[float], elements_names: Sequence[str], nugget: Optional[Sequence[float]] = None) -> gempy.core.data.structural_frame.StructuralFrame Add surface points to the geological model. This function adds surface points to the specified geological elements in the model. The points are grouped by element names, and optional nugget values can be specified for each point. Args: geo_model (GeoModel): The geological model to which the surface points will be added. x (Sequence[float]): Sequence of x-coordinates for the surface points. y (Sequence[float]): Sequence of y-coordinates for the surface points. z (Sequence[float]): Sequence of z-coordinates for the surface points. elements_names (Sequence[str]): Sequence of element names corresponding to each surface point. nugget (Optional[Sequence[float]]): Sequence of nugget values for each surface point. If not provided, a default value will be used for all points. Returns: StructuralFrame: The updated structural frame of the geological model. Raises: ValueError: If the length of the nugget sequence does not match the lengths of the other input sequences. calculate_gravity_gradient(centered_grid: gempy_engine.core.data.centered_grid.CenteredGrid, ugal=True) -> numpy.ndarray compute_model(gempy_model: gempy.core.data.geo_model.GeoModel, engine_config: Optional[gempy.core.data.gempy_engine_config.GemPyEngineConfig] = None) -> gempy_engine.core.data.solutions.Solutions Compute the geological model given the provided GemPy model. Args: gempy_model (GeoModel): The GemPy model to compute. engine_config (Optional[GemPyEngineConfig]): Configuration for the computational engine. Defaults to None, in which case a default configuration will be used. Raises: ValueError: If the provided backend in the engine_config is not supported. Returns: Solutions: The computed geological model. compute_model_at(gempy_model: gempy.core.data.geo_model.GeoModel, at: numpy.ndarray, engine_config: Optional[gempy.core.data.gempy_engine_config.GemPyEngineConfig] = None) -> numpy.ndarray Compute the geological model at specific coordinates. Note: This function sets a custom grid and computes the model so be wary of side effects. Args: gempy_model (GeoModel): The GemPy model to compute. at (np.ndarray): The coordinates at which to compute the model. engine_config (Optional[GemPyEngineConfig], optional): Configuration for the computational engine. Defaults to None, in which case a default configuration will be used. Returns: np.ndarray: The computed geological model at the specified coordinates. create_data_legacy(*, project_name: str = 'default_project', extent: Union[list, numpy.ndarray] = None, resolution: Union[list, numpy.ndarray] = None, path_i: str = None, path_o: str = None) -> gempy.core.data.geo_model.GeoModel create_geomodel(*, project_name: str = 'default_project', extent: Union[list, numpy.ndarray] = None, resolution: Union[list, numpy.ndarray] = None, refinement: int = 1, structural_frame: gempy.core.data.structural_frame.StructuralFrame = None, importer_helper: gempy.core.data.importer_helper.ImporterHelper = None) -> gempy.core.data.geo_model.GeoModel Initializes and returns a GeoModel instance with specified parameters. Args: project_name (str, optional): The name of the project. Defaults to 'default_project'. extent (Union[List, np.ndarray], optional): The 3D extent of the grid. Must be provided if resolution is specified. Defaults to None. resolution (Union[List, np.ndarray], optional): The resolution of the grid. If None, an octree grid will be initialized. Defaults to None. refinement (int, optional): The level of refinement for the octree grid. Defaults to 1. structural_frame (StructuralFrame, optional): The structural frame of the GeoModel. Either this or importer_helper must be provided. Defaults to None. importer_helper (ImporterHelper, optional): Helper object for importing structural elements. Either this or structural_frame must be provided. Defaults to None. Returns: GeoModel: The initialized GeoModel object. Raises: ValueError: If neither structural_frame nor importer_helper is provided. create_orientations_from_surface_points_coords(xyz_coords: numpy.ndarray, subset: Optional[numpy.ndarray] = None, element_name: Optional[str] = 'Generated') -> gempy.core.data.orientations.OrientationsTable delete_orientations() delete_surface_points() generate_example_model(example_model: gempy.core.data.enumerators.ExampleModel, compute_model: bool = True) -> gempy.core.data.geo_model.GeoModel map_stack_to_surfaces(gempy_model: gempy.core.data.geo_model.GeoModel, mapping_object: Union[dict[str, list[str]], dict[str, tuple]], set_series: bool = True, remove_unused_series=True) -> gempy.core.data.structural_frame.StructuralFrame Map stack (series) to surfaces by reorganizing elements between groups in a GeoModel's structural frame. This function reorganizes structural elements (surfaces) based on a mapping object and updates the structural frame of the GeoModel. It can also create new series and remove unused ones. Args: gempy_model (GeoModel): The GeoModel object whose structural frame is to be modified. mapping_object (Union[dict[str, list[str]] | dict[str, tuple]]): Dictionary mapping group names to element names. set_series (bool, optional): If True, creates new series for groups not present in the GeoModel. Defaults to True. remove_unused_series (bool, optional): If True, removes groups without any elements. Defaults to True. Returns: StructuralFrame: The updated StructuralFrame object. modify_orientations(geo_model: gempy.core.data.geo_model.GeoModel, slice: Union[int, slice, NoneType] = None, **orientation_field: Union[float, numpy.ndarray]) -> gempy.core.data.structural_frame.StructuralFrame Modifies specified fields of all orientations in the structural frame. The keys of the orientation_field dictionary should match the field names in the orientations (e.g., "X", "Y", "Z", "G_x", "G_y", "G_z", "nugget"). Args: geo_model (GeoModel): The GeoModel instance to modify. slice (Optional[Union[int, slice]]): The slice of orientations to modify. If None, all orientations will be modified. Keyword Args: X (Union[float, np.ndarray]): X coordinates of the orientations. Y (Union[float, np.ndarray]): Y coordinates of the orientations. Z (Union[float, np.ndarray]): Z coordinates of the orientations. azimuth (Union[float, np.ndarray]): Azimuth angles of the orientations. dip (Union[float, np.ndarray]): Dip angles of the orientations. polarity (Union[float, np.ndarray]): Polarity values of the orientations. G_x (Union[float, np.ndarray]): X component of the gradient vector. G_y (Union[float, np.ndarray]): Y component of the gradient vector. G_z (Union[float, np.ndarray]): Z component of the gradient vector. nugget (Union[float, np.ndarray]): Nugget value of the orientations. Returns: StructuralFrame: The modified structural frame. modify_surface_points(geo_model: gempy.core.data.geo_model.GeoModel, slice: Union[int, slice, NoneType] = None, elements_names: Optional[Sequence[str]] = None, **surface_points_field: Union[float, numpy.ndarray]) -> gempy.core.data.structural_frame.StructuralFrame Modifies specified fields of all surface points in the structural frame. The keys of the surface_points_field dictionary should match the field names in the surface points (e.g., "X", "Y", "Z", "nugget"). Args: geo_model (GeoModel): The GeoModel instance to modify. slice (Optional[Union[int, slice]]): The slice of surface points to modify. If None, all surface points will be modified. Keyword Args: X (Union[float, np.ndarray]): X coordinates of the surface points. Y (Union[float, np.ndarray]): Y coordinates of the surface points. Z (Union[float, np.ndarray]): Z coordinates of the surface points. nugget (Union[float, np.ndarray]): Nugget value of the surface points. Returns: StructuralFrame: The modified structural frame. remove_element_by_name(model: gempy.core.data.geo_model.GeoModel, element_name: str) -> gempy.core.data.structural_frame.StructuralFrame remove_structural_group_by_index(model: gempy.core.data.geo_model.GeoModel, group_index: int) -> gempy.core.data.structural_frame.StructuralFrame remove_structural_group_by_name(model: gempy.core.data.geo_model.GeoModel, group_name: str) -> gempy.core.data.structural_frame.StructuralFrame set_active_grid(grid: gempy.core.data.grid.Grid, grid_type: list[gempy.core.data.grid.Grid.GridTypes], reset: bool = False) set_centered_grid(grid: gempy.core.data.grid.Grid, centers: numpy.ndarray, resolution: Sequence[float], radius: Union[float, Sequence[float]]) set_custom_grid(grid: gempy.core.data.grid.Grid, xyz_coord: numpy.ndarray) set_fault_relation(frame: Union[gempy.core.data.geo_model.GeoModel, gempy.core.data.structural_frame.StructuralFrame], rel_matrix: numpy.ndarray) -> gempy.core.data.structural_frame.StructuralFrame Sets the fault relations in the structural frame of the GeoModel. Args: frame (Union[GeoModel, StructuralFrame]): GeoModel or its StructuralFrame to be modified. rel_matrix (np.ndarray): Fault relation matrix to be set. Returns: StructuralFrame: The updated StructuralFrame object. set_is_fault(frame: Union[gempy.core.data.geo_model.GeoModel, gempy.core.data.structural_frame.StructuralFrame], fault_groups: Union[list[str], list[gempy.core.data.structural_group.StructuralGroup]], faults_relation_type: gempy.core.data.structural_group.FaultsRelationSpecialCase = <FaultsRelationSpecialCase.OFFSET_FORMATIONS: 1>, change_color: bool = True) -> gempy.core.data.structural_frame.StructuralFrame Sets given groups as fault in the structural frame of the GeoModel. It can optionally change the color of these groups. Args: frame (Union[GeoModel, StructuralFrame]): GeoModel or its StructuralFrame to be modified. fault_groups (Union[list[str], list[StructuralGroup]]): Groups to be set as faults. faults_relation_type (FaultsRelationSpecialCase, optional): Faults relation type to be set. Defaults to FaultsRelationSpecialCase.OFFSET_FORMATIONS. change_color (bool, optional): If True, changes the color of the fault groups. Defaults to True. Returns: StructuralFrame: The updated StructuralFrame object. set_is_finite_fault(self, series_fault=None, toggle: bool = True) set_section_grid(grid: gempy.core.data.grid.Grid, section_dict: dict) set_topography_from_arrays(grid: gempy.core.data.grid.Grid, xyz_vertices: numpy.ndarray) set_topography_from_file(grid: gempy.core.data.grid.Grid, filepath: str, crop_to_extent: Optional[Sequence] = None) set_topography_from_random(grid: gempy.core.data.grid.Grid, fractal_dimension: float = 2.0, d_z: Optional[Sequence] = None, topography_resolution: Optional[Sequence] = None) Sets the topography of the grid using a randomly generated topography. Args: grid (Grid): The grid object on which to set the topography. fractal_dimension (float, optional): The fractal dimension of the random topography. Defaults to 2.0. d_z (Union[Sequence, None], optional): The sequence of elevation increments for the random topography. If None, a default sequence will be used. Defaults to None. topography_resolution (Union[Sequence, None], optional): The resolution of the random topography. If None, the resolution of the grid's regular grid will be used. Defaults to None. Returns: The topography object that was set on the grid. Example: >>> grid = Grid() >>> set_topography_from_random(grid, fractal_dimension=1.5, d_z=[0.1, 0.2, 0.3], topography_resolution=[10, 10]) Note: If topography_resolution is None, the resolution of the grid's regular grid will be used. If d_z is None, a default sequence of elevation increments will be used. set_topography_from_subsurface_structured_grid(grid: gempy.core.data.grid.Grid, struct: 'subsurface.StructuredData') structural_elements_from_borehole_set(borehole_set: 'subsurface.core.geological_formats.BoreholeSet', elements_dict: dict) -> list[gempy.core.data.structural_element.StructuralElement] Creates a list of StructuralElements from a BoreholeSet. Args: borehole_set (subsurface.core.geological_formats.BoreholeSet): The BoreholeSet object containing the boreholes. elements_dict (dict): A dictionary containing the properties of the structural elements to be created. Returns: list[StructuralElement]: A list of StructuralElement objects created from the borehole set. Raises: ValueError: If a top lithology ID specified in `elements_dict` is not found in the borehole set. DATA __all__ = ['create_data_legacy', 'create_geomodel', 'structural_elemen... FILE f:\pythonproject\gempy-main.venv\lib\site-packages\gempy\api\__init__.py Help on package gempy.core in gempy: NAME gempy.core PACKAGE CONTENTS color_generator data (package) FILE f:\pythonproject\gempy-main.venv\lib\site-packages\gempy\core\__init__.py Help on package gempy_engine.API in gempy_engine: NAME gempy_engine.API PACKAGE CONTENTS _version dual_contouring (package) interp_single (package) model (package) server (package) FILE f:\pythonproject\gempy-main.venv\lib\site-packages\gempy_engine\api\__init__.py Help on package gempy_engine: NAME gempy_engine PACKAGE CONTENTS API (package) _version config core (package) modules (package) optional_dependencies plugins (package) VERSION 2024.2.0 FILE f:\pythonproject\gempy-main.venv\lib\site-packages\gempy_engine\__init__.py Process finished with exit code 0
最新发布
11-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值