| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -86,38 +86,38 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            spdlog::warn("using Eigen built-in direct solver!"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#endif | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // start iteration
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            while (change > sp_para_->tol_x*1 && loop < sp_para_->max_loop) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            while (change > sp_para_->tol_x * 1 && loop < sp_para_->max_loop) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                ++loop; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // filter
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                xPhys_col = sp_mech_top3d_->H_ * (xPhys_col.array() / sp_mech_top3d_->Hs_.array()).matrix().eval(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalR = [](double rho, double R) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return rho / (1.0 + R * (1.0 - rho)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalR_Vec=[](const Eigen::VectorXd& vec_rho,double R)->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return vec_rho.array()/(1.0+R*(1.0-vec_rho.array())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalR_Vec = [](const Eigen::VectorXd &vec_rho, double R) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return vec_rho.array() / (1.0 + R * (1.0 - vec_rho.array())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDRDrho = [](double rho, double R) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    double down = 1 + R * (1 - rho); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return (1 + R) / down * down; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDRDrho_Vec=[](const Eigen::VectorXd&vec_rho,double R)->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto down=1+R*(1-vec_rho.array()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return (1+R)/down.pow(2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDRDrho_Vec = [](const Eigen::VectorXd &vec_rho, double R) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto down = 1 + R * (1 - vec_rho.array()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return (1 + R) / down.pow(2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalE_Vec = [&](const Eigen::VectorXd& vec_rho)->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalE_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalR_Vec(vec_rho, sp_para_->R_E) * E0_m; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDEDrho_Vec=[&](const Eigen::VectorXd& vec_rho)->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalDRDrho_Vec(vec_rho,sp_para_->R_E) * E0_m; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDEDrho_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalDRDrho_Vec(vec_rho, sp_para_->R_E) * E0_m; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalLambda_Vec = [&](const Eigen::VectorXd &vec_rho) ->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalLambda_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return lambda_min + CalR_Vec(vec_rho, sp_para_->R_lambda).array() * (lambda0 - lambda_min); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDlambdaDrho = [&](double rho) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalDRDrho(rho, sp_para_->R_lambda) * (lambda0 - lambda_min); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDlambdaDrho_Vec=[&](const Eigen::VectorXd& vec_rho)->Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalDRDrho_Vec(vec_rho,sp_para_->R_lambda) *(lambda0-lambda_min); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalDlambdaDrho_Vec = [&](const Eigen::VectorXd &vec_rho) -> Eigen::VectorXd { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return CalDRDrho_Vec(vec_rho, sp_para_->R_lambda) * (lambda0 - lambda_min); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto CalBeta = [&](double rho) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -129,10 +129,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // solve T
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd sK_th = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        (sp_thermal_top3d_->sKe_ * (lambda_min + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                    xPhys_col.array() / | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                    (1.0 + sp_para_->R_lambda * (1.0 - xPhys_col.array())) * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                    (lambda0 - lambda_min)).matrix().transpose()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        (sp_thermal_top3d_->sKe_ * CalLambda_Vec(xPhys_col).transpose()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                .reshaped(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto v_tri_th = Vec2Triplet(sp_thermal_top3d_->iK_, sp_thermal_top3d_->jK_, sK_th); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                sp_thermal_top3d_->K_.setFromTriplets(v_tri_th.begin(), v_tri_th.end()); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -149,12 +146,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // solve U
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd sK_m = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        (sp_mech_top3d_->sKe_ * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                xPhys_col.array() / | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                (1.0 + sp_para_->R_E * (1.0 - xPhys_col.array())) * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                E0_m).matrix() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                .transpose()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        (sp_mech_top3d_->sKe_ * CalE_Vec(xPhys_col).transpose()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                .reshaped(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto v_tri_m = Vec2Triplet(sp_mech_top3d_->iK_, sp_mech_top3d_->jK_, sK_m); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                sp_mech_top3d_->K_.setFromTriplets(v_tri_m.begin(), v_tri_m.end()); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -188,9 +180,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ce(i) = Ue.transpose() * sp_mech_top3d_->Ke_ * Ue; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                double c = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        ce.transpose() * (xPhys_col.array() / | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                          (1.0 + sp_para_->R_E * (1.0 - xPhys_col.array())) * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                          E0_m).matrix(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        ce.transpose() * CalE_Vec(xPhys_col); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                double v = flg_chosen ? xPhys_col(chosen_ele_id).sum() : xPhys_col.sum(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // sensitivity
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -242,7 +232,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::SparseMatrix<double> &dF_drho = dFth_drho; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // lambda_m_Mul_dKm_drho_Mul_U
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd lambda_m_Mul_dKm_drho_Mul_U = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        -((1 + sp_para_->R_E) / (1.0 + sp_para_->R_E * (1.0 - xPhys_col.array())).pow(2)) * ce.array(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        -CalDEDrho_Vec(xPhys_col).array() * ce.array(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // lambda_t_Mul_dKt_drho_Mul_T
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd ce_th(sp_thermal_top3d_->sp_mesh_->GetNumEles()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (int i = 0; i < sp_thermal_top3d_->sp_mesh_->GetNumEles(); ++i) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -251,23 +241,19 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Eigen::VectorXd lambda_t_e = lambda_t(dofs_in_ele_i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ce_th(i) = lambda_t_e.transpose() * sp_thermal_top3d_->Ke_ * Te; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd lambda_t_Mul_dKt_drho_Mul_T = ((1 + (lambda0 - lambda_min)) / | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                               (1.0 + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                                (lambda0 - lambda_min) * (1.0 - xPhys_col.array())).pow( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                                       2)) * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                              ce_th.array(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd lambda_t_Mul_dKt_drho_Mul_T = CalDlambdaDrho_Vec(xPhys_col).array() * ce_th.array(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // dc_drho
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                Eigen::VectorXd dc_drho = lambda_t_Mul_dKt_drho_Mul_T +
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                          lambda_m_Mul_dKm_drho_Mul_U +
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                          2 * Eigen::VectorXd(dF_drho * sp_mech_top3d_->U_);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd dc_drho = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::VectorXd dc_drho = lambda_t_Mul_dKt_drho_Mul_T + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                          lambda_m_Mul_dKm_drho_Mul_U + | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                          2 * Eigen::VectorXd(dF_drho * sp_mech_top3d_->U_); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                Eigen::VectorXd dc_drho =
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                        lambda_m_Mul_dKm_drho_Mul_U +
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                        2 * Eigen::VectorXd(dF_drho * sp_mech_top3d_->U_);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // dT_drho
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                Eigen::MatrixXd dT_drho = Eigen::MatrixXd::Zero(sp_thermal_top3d_->sp_mesh_->GetNumEles(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                                sp_thermal_top3d_->set_dofs_to_load.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for(auto it=map_ele2Limit.begin();it!=map_ele2Limit.end();++it){ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto [ele_id,v_limited]=*it; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto it = map_ele2Limit.begin(); it != map_ele2Limit.end(); ++it) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto [ele_id, v_limited] = *it; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Eigen::VectorXi dofs_in_ele_i = sp_thermal_top3d_->sp_mesh_->MapEleId2Dofs(ele_id); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Eigen::VectorXd dKe_th_Mul_T = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            CalDlambdaDrho(xPhys_col(ele_id)) * sp_thermal_top3d_->Ke_ * T(dofs_in_ele_i); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -280,7 +266,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    Eigen::VectorXd ele_dT_drho = Ke_th.llt().solve(-dKe_th_Mul_T); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for(auto &limited:v_limited){ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto &limited: v_limited) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        dT_drho(ele_id, limited.idx_of_load_dof) = ele_dT_drho(limited.idx_in_ele); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -339,7 +325,7 @@ namespace da::sha::top { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                spdlog::critical("Iter: {:3d}, Comp: {:.3e}, Vol: {:.2f}, Change: {:f}", loop, c, v, change); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::cout<<fval.transpose()<<std::endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::cout << fval.transpose() << std::endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#ifdef WRITE_TENSOR_IN_LOOP | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // extract vtk
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ele_to_write(pixel_idx) = xPhys_col; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |