/*differential_of_f: term in gamma integrand only for absorptivity calculation; *it is the differential Df = 2\pi\nu (1/(mc)*d/dgamma + (beta cos(theta) * -cos(xi))/(p*beta*c) * d/d(cos(xi))) f *this is eq. 41 of [1] *below it is applied for the THERMAL, POWER_LAW, and KAPPA_DIST distributions *@param gamma: Input, Lorentz factor *@param nu: Input, frequency of emission/absorption *@returns: Output, Df term in gamma integrand; depends on distribution function */ double differential_of_f(double gamma, double nu) { #if DISTRIBUTION_FUNCTION == THERMAL double prefactor = (M_PI * nu / (mass_electron*speed_light*speed_light)) * (n_e/(theta_e * gsl_sf_bessel_Kn(2, 1./theta_e))); double body = (-1./theta_e) * exp(-gamma/theta_e); double f = prefactor * body; #elif DISTRIBUTION_FUNCTION == POWER_LAW double pl_norm = 4.* M_PI/(normalize_f()); double prefactor = (M_PI * nu / (mass_electron*speed_light*speed_light)) * (n_e_NT*(power_law_p-1.)) /((pow(gamma_min, 1.-power_law_p) - pow(gamma_max, 1.-power_law_p))); double term1 = ((-power_law_p-1.)*exp(-gamma/gamma_cutoff) *pow(gamma,-power_law_p-2.)/(sqrt(gamma*gamma - 1.))); double term2 = (exp(-gamma/gamma_cutoff) * pow(gamma,(-power_law_p-1.)) /(gamma_cutoff * sqrt(gamma*gamma - 1.))); double term3 = (exp(-gamma/gamma_cutoff) * pow(gamma,-power_law_p)) /pow((gamma*gamma - 1.), (3./2.)); double f = pl_norm * prefactor * (term1 - term2 - term3); #elif DISTRIBUTION_FUNCTION == KAPPA_DIST double prefactor = n_e * (1./normalize_f()) * 4. * M_PI*M_PI * nu * mass_electron*mass_electron * speed_light; double term1 = ((- kappa - 1.) / (kappa * w)) * pow((1. + (gamma - 1.) /(kappa * w)), -kappa-2.); double term2 = pow((1. + (gamma - 1.)/(kappa * w)), (- kappa - 1.)) * (- 1./gamma_cutoff); double f = prefactor * (term1 + term2) * exp(-gamma/gamma_cutoff); #endif return f; }
/*kappa_f: kappa distribution function, numerically normalized *uses eq. 42 of [2] *@param gamma: Input, Lorentz factor *@returns: normalized kappa distribution function to go into gamma integrand */ double kappa_f(double gamma) { double norm = 1./normalize_f(); double kappa_body = n_e * pow((1. + (gamma - 1.)/(kappa * w)), -kappa-1); double cutoff = exp(-gamma/gamma_cutoff); //double ans = norm * kappa_body * cutoff; double ans = norm * kappa_body; return ans; }
/*power_law_f: power-law distribution function, normalized via call to the * normalize_f() function. Uses eq. 50 of [1]. *@param gamma: Input, Lorentz factor *@returns: Ouput, a normalized power-law distribution for the gamma integrand */ double power_law_f(double gamma) { double beta = sqrt(1. - 1./(gamma*gamma)); double prefactor = n_e_NT * (power_law_p - 1.) / (pow(gamma_min, 1. - power_law_p) - pow(gamma_max, 1. - power_law_p)); //double body = pow(gamma, -p) * exp(- gamma / gamma_cutoff); double body = pow(gamma, -power_law_p); double ans = 1./normalize_f() * prefactor * body * 1./(pow(mass_electron, 3.) * pow(speed_light, 3.) * gamma*gamma * beta); return ans; }
// // MQO // void build_from_mqo( mqo_reader::document_type& doc, float scale, const Color& color) { // マテリアル for (const auto& ms: doc.materials) { Piece m; m.vbo = 0; m.ibo = 0; #ifdef JSTEXTURE m.texture = ""; #else m.texture = 0; #endif m.color.rgba[0] = ms.color.red; m.color.rgba[1] = ms.color.green; m.color.rgba[2] = ms.color.blue; m.color.rgba[3] = ms.color.alpha; if (ms.texture != "") { #ifdef JSTEXTURE m.texture = ms.texture; loadTexture(m.texture.c_str()); #else m.texture = build_texture(ms.texture.c_str()); #endif } pieces_.push_back(m); } { // default material Piece m; m.vbo = 0; m.ibo = 0; #ifdef JSTEXTURE m.texture = ""; #else m.texture = 0; #endif m.color = color; pieces_.push_back(m); } // 頂点, 面 for (const auto& pair: doc.objects) { const mqo_reader::object_type& obj = pair.second; // dictionary: // (source vertex index, uv ) => destination vertex index struct VertexKey { int index; float u; float v; VertexKey(){} VertexKey(int aindex, float au, float av) : index(aindex), u(au), v(av) {} bool operator<(const VertexKey& a) const { if (index < a.index) { return true; } if (a.index < index) { return false; } if (u < a.u) { return true; } if (a.u < u) { return false; } return v < a.v; } }; std::vector<std::map<VertexKey, int>> used_vertices; used_vertices.resize(pieces_.size()); // マテリアルごとに使用頂点を分類 for (const auto& face: obj.faces) { int material_index = face.material_index; if (material_index == -1) { material_index = int(pieces_.size() - 1); } int i0 = face.vertex_indices[0]; int i1 = face.vertex_indices[1]; int i2 = face.vertex_indices[2]; std::map<VertexKey, int>& c = used_vertices[material_index]; c[VertexKey(i0, face.uv[0].u, face.uv[0].v)] = -1; c[VertexKey(i1, face.uv[1].u, face.uv[1].v)] = -1; c[VertexKey(i2, face.uv[2].u, face.uv[2].v)] = -1; } // マテリアルごとに使われている頂点を追加 size_t n = pieces_.size(); for (size_t i = 0 ; i < n ; i++) { Piece& m = pieces_[i]; std::map<VertexKey, int>& c = used_vertices[i]; int no = int(m.vertex_source.size()); for (auto& j: c) { const auto& src = obj.vertices[j.first.index]; Piece::Vertex dst; dst.position = Vector( src.x * scale, src.y * scale, src.z * -scale); dst.normal = Vector(0, 0, 0); dst.diffuse = m.color; dst.u = j.first.u; dst.v = j.first.v; m.vertex_source.push_back(dst); j.second = no++; } } // マテリアルごとに面を追加 for (const auto& face: obj.faces) { int material_index = face.material_index; if (material_index == -1) { material_index = int(pieces_.size()- 1); } int i0 = face.vertex_indices[0]; int i1 = face.vertex_indices[1]; int i2 = face.vertex_indices[2]; std::map<VertexKey, int>& c = used_vertices[material_index]; int k0 = c[VertexKey(i0, face.uv[0].u, face.uv[0].v)]; int k1 = c[VertexKey(i1, face.uv[1].u, face.uv[1].v)]; int k2 = c[VertexKey(i2, face.uv[2].u, face.uv[2].v)]; Piece& m = pieces_[material_index]; m.index_source.push_back(k0); m.index_source.push_back(k1); m.index_source.push_back(k2); Piece::Vertex& v0 = m.vertex_source[k0]; Piece::Vertex& v1 = m.vertex_source[k1]; Piece::Vertex& v2 = m.vertex_source[k2]; Vector normal = cross( v1.position - v0.position, v2.position - v0.position); v0.normal += normal; v1.normal += normal; v2.normal += normal; } } // 法線後処理 for (Piece& m: pieces_) { for (auto& v: m.vertex_source) { normalize_f(v.normal); } } build_pieces(); }